1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2002 Cluster File Systems, Inc.
5 * Author: Phil Schwan <phil@clusterfs.com>
7 * This file is part of Lustre, http://www.lustre.org.
9 * Lustre is free software; you can redistribute it and/or
10 * modify it under the terms of version 2 of the GNU General Public
11 * License as published by the Free Software Foundation.
13 * Lustre is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with Lustre; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 * Darwin porting library
23 * Make things easy to port
26 #include <mach/mach_types.h>
28 #include <sys/mount.h>
30 #include <netinet/in.h>
31 #include <netinet/tcp.h>
32 #include <sys/socket.h>
33 #include <sys/socketvar.h>
34 #include <sys/sockio.h>
35 #include <sys/protosw.h>
38 #define DEBUG_SUBSYSTEM S_LNET
40 #include <libcfs/libcfs.h>
41 #include <libcfs/kp30.h>
43 static __inline__ struct sockaddr_in
46 struct sockaddr_in blank = { sizeof(struct sockaddr_in), AF_INET };
51 libcfs_ipif_free_enumeration (char **names, int n)
57 for (i = 0; i < n && names[i] != NULL; i++)
58 LIBCFS_FREE(names[i], IFNAMSIZ);
60 LIBCFS_FREE(names, n * sizeof(*names));
67 * No hack kernel structre, all using KPI.
71 libcfs_ipif_query (char *name, int *up, __u32 *ip, __u32 *mask)
79 rc = -sock_socket(PF_INET, SOCK_STREAM, 0,
82 CERROR ("Can't create socket: %d\n", rc);
86 nob = strnlen(name, IFNAMSIZ);
87 if (nob == IFNAMSIZ) {
88 CERROR("Interface name %s too long\n", name);
93 CLASSERT (sizeof(ifr.ifr_name) >= IFNAMSIZ);
94 bzero(&ifr, sizeof(ifr));
95 strcpy(ifr.ifr_name, name);
96 rc = -sock_ioctl (so, SIOCGIFFLAGS, &ifr);
99 CERROR("Can't get flags for interface %s\n", name);
103 if ((ifr.ifr_flags & IFF_UP) == 0) {
104 CDEBUG(D_NET, "Interface %s down\n", name);
112 bzero(&ifr, sizeof(ifr));
113 strcpy(ifr.ifr_name, name);
114 *((struct sockaddr_in *)&ifr.ifr_addr) = blank_sin();
115 rc = -sock_ioctl(so, SIOCGIFADDR, &ifr);
118 CERROR("Can't get IP address for interface %s\n", name);
122 val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
125 bzero(&ifr, sizeof(ifr));
126 strcpy(ifr.ifr_name, name);
127 *((struct sockaddr_in *)&ifr.ifr_addr) = blank_sin();
128 rc = -sock_ioctl(so, SIOCGIFNETMASK, &ifr);
131 CERROR("Can't get netmask for interface %s\n", name);
135 val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
143 libcfs_ipif_enumerate (char ***namesp)
145 /* Allocate and fill in 'names', returning # interfaces/error */
157 rc = -sock_socket(PF_INET, SOCK_STREAM, 0,
160 CERROR ("Can't create socket: %d\n", rc);
164 nalloc = 16; /* first guess at max interfaces */
167 if (nalloc * sizeof(*ifr) > CFS_PAGE_SIZE) {
169 nalloc = CFS_PAGE_SIZE/sizeof(*ifr);
170 CWARN("Too many interfaces: only enumerating first %d\n",
174 LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr));
176 CERROR ("ENOMEM enumerating up to %d interfaces\n", nalloc);
181 ifc.ifc_buf = (char *)ifr;
182 ifc.ifc_len = nalloc * sizeof(*ifr);
187 * sock_ioctl(..., SIOCGIFCONF, ...) is not supposed to be used in
188 * kernel space because it always try to copy result to userspace.
189 * So we can't get interfaces name by sock_ioctl(...,SIOCGIFCONF,...).
190 * I've created a bug for Apple, let's wait...
193 for (i = 0; i < 16; i++) {
195 bzero(&en, sizeof(en));
196 snprintf(en.ifr_name, IFNAMSIZ, "en%d", i);
197 rc = -sock_ioctl (so, SIOCGIFFLAGS, &en);
200 strcpy(ifr[nfound++].ifr_name, en.ifr_name);
203 #else /* NOT in using now */
204 rc = -sock_ioctl(so, SIOCGIFCONF, (caddr_t)&ifc);
207 CERROR ("Error %d enumerating interfaces\n", rc);
211 nfound = ifc.ifc_len/sizeof(*ifr);
212 LASSERT (nfound <= nalloc);
215 if (nfound < nalloc || toobig)
218 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
224 LIBCFS_ALLOC(names, nfound * sizeof(*names));
229 /* NULL out all names[i] */
230 memset (names, 0, nfound * sizeof(*names));
232 for (i = 0; i < nfound; i++) {
234 nob = strnlen (ifr[i].ifr_name, IFNAMSIZ);
235 if (nob == IFNAMSIZ) {
236 /* no space for terminating NULL */
237 CERROR("interface name %.*s too long (%d max)\n",
238 nob, ifr[i].ifr_name, IFNAMSIZ);
243 LIBCFS_ALLOC(names[i], IFNAMSIZ);
244 if (names[i] == NULL) {
249 memcpy(names[i], ifr[i].ifr_name, nob);
258 libcfs_ipif_free_enumeration(names, nfound);
260 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
268 * Public entry of socket upcall.
270 * so_upcall can only be installed while create/accept of socket in
271 * Darwin 8.0, so we setup libcfs_sock_upcall() as upcall for all
272 * sockets in creat/accept, it will call upcall provided by user
273 * which can be setup after create/accept of socket.
275 static void libcfs_sock_upcall(socket_t so, void* arg, int waitf)
279 sock = (cfs_socket_t *)arg;
280 LASSERT(sock->s_magic == CFS_SOCK_MAGIC);
282 if ((sock->s_flags & CFS_SOCK_UPCALL) != 0 && sock->s_upcall != NULL)
283 sock->s_upcall(so, sock->s_upcallarg, waitf);
287 void libcfs_sock_set_cb(cfs_socket_t *sock, so_upcall callback, void *arg)
289 sock->s_upcall = callback;
290 sock->s_upcallarg = arg;
291 sock->s_flags |= CFS_SOCK_UPCALL;
295 void libcfs_sock_reset_cb(cfs_socket_t *sock)
297 sock->s_flags &= ~CFS_SOCK_UPCALL;
298 sock->s_upcall = NULL;
299 sock->s_upcallarg = NULL;
304 libcfs_sock_create (cfs_socket_t **sockp, int *fatal,
305 __u32 local_ip, int local_port)
307 struct sockaddr_in locaddr;
313 /* All errors are fatal except bind failure if the port is in use */
316 sock = _MALLOC(sizeof(cfs_socket_t), M_TEMP, M_WAITOK|M_ZERO);
318 CERROR("Can't allocate cfs_socket.\n");
322 sock->s_magic = CFS_SOCK_MAGIC;
324 rc = -sock_socket(PF_INET, SOCK_STREAM, 0,
325 libcfs_sock_upcall, sock, &C2B_SOCK(sock));
329 optlen = sizeof(option);
330 rc = -sock_setsockopt(C2B_SOCK(sock), SOL_SOCKET,
331 SO_REUSEADDR, &option, optlen);
335 /* can't specify a local port without a local IP */
336 LASSERT (local_ip == 0 || local_port != 0);
338 if (local_ip != 0 || local_port != 0) {
339 bzero (&locaddr, sizeof (locaddr));
340 locaddr.sin_len = sizeof(struct sockaddr_in);
341 locaddr.sin_family = AF_INET;
342 locaddr.sin_port = htons (local_port);
343 locaddr.sin_addr.s_addr = (local_ip != 0) ? htonl(local_ip) : INADDR_ANY;
344 rc = -sock_bind(C2B_SOCK(sock), (struct sockaddr *)&locaddr);
345 if (rc == -EADDRINUSE) {
346 CDEBUG(D_NET, "Port %d already in use\n", local_port);
351 CERROR("Error trying to bind to port %d: %d\n",
358 if (C2B_SOCK(sock) != NULL)
359 sock_close(C2B_SOCK(sock));
365 libcfs_sock_listen (cfs_socket_t **sockp,
366 __u32 local_ip, int local_port, int backlog)
372 rc = libcfs_sock_create(&sock, &fatal, local_ip, local_port);
375 CERROR("Can't create socket: port %d already in use\n",
380 rc = -sock_listen(C2B_SOCK(sock), backlog);
386 if (C2B_SOCK(sock) != NULL)
387 sock_close(C2B_SOCK(sock));
393 libcfs_sock_accept (cfs_socket_t **newsockp, cfs_socket_t *sock)
395 cfs_socket_t *newsock;
398 newsock = _MALLOC(sizeof(cfs_socket_t), M_TEMP, M_WAITOK|M_ZERO);
400 CERROR("Can't allocate cfs_socket.\n");
403 newsock->s_magic = CFS_SOCK_MAGIC;
405 * thread will sleep in sock_accept by calling of msleep(),
406 * it can be interrupted because msleep() use PCATCH as argument.
408 rc = -sock_accept(C2B_SOCK(sock), NULL, 0, 0,
409 libcfs_sock_upcall, newsock, &C2B_SOCK(newsock));
411 if (C2B_SOCK(newsock) != NULL)
412 sock_close(C2B_SOCK(newsock));
413 FREE(newsock, M_TEMP);
414 if ((sock->s_flags & CFS_SOCK_DOWN) != 0)
415 /* shutdown by libcfs_sock_abort_accept(), fake
416 * error number for lnet_acceptor() */
425 libcfs_sock_abort_accept (cfs_socket_t *sock)
430 * we want to wakeup thread blocked by sock_accept, but we don't
431 * know the address where thread is sleeping on, so we cannot
432 * wakeup it directly.
433 * The thread slept in sock_accept will be waken up while:
434 * 1. interrupt by signal
435 * 2. new connection is coming (sonewconn)
436 * 3. disconnecting of the socket (soisconnected)
438 * Cause we can't send signal to a thread directly(no KPI), so the
439 * only thing can be done here is disconnect the socket (by
440 * sock_shutdown() or sth else? ).
442 * Shutdown request of socket with SHUT_WR or SHUT_RDWR will
443 * be issured to the protocol.
444 * sock_shutdown()->tcp_usr_shutdown()->tcp_usrclosed()->
445 * tcp_close()->soisdisconnected(), it will wakeup thread by
446 * wakeup((caddr_t)&so->so_timeo);
448 sock->s_flags |= CFS_SOCK_DOWN;
449 sock_shutdown(C2B_SOCK(sock), SHUT_RDWR);
453 libcfs_sock_read (cfs_socket_t *sock, void *buffer, int nob, int timeout)
457 cfs_duration_t to = cfs_time_seconds(timeout);
468 struct msghdr msg = {
477 cfs_duration_usec(to, &tv);
478 rc = -sock_setsockopt(C2B_SOCK(sock), SOL_SOCKET, SO_RCVTIMEO,
481 CERROR("Can't set socket recv timeout "
483 (long)tv.tv_sec, (int)tv.tv_usec, rc);
487 then = cfs_time_current();
488 rc = -sock_receive(C2B_SOCK(sock), &msg, 0, &rcvlen);
489 to -= cfs_time_current() - then;
491 if (rc != 0 && rc != -EWOULDBLOCK)
499 buffer = ((char *)buffer) + rcvlen;
506 libcfs_sock_write (cfs_socket_t *sock, void *buffer, int nob, int timeout)
510 cfs_duration_t to = cfs_time_seconds(timeout);
521 struct msghdr msg = {
528 .msg_flags = (timeout == 0) ? MSG_DONTWAIT : 0,
532 cfs_duration_usec(to, &tv);
533 rc = -sock_setsockopt(C2B_SOCK(sock), SOL_SOCKET, SO_SNDTIMEO,
536 CERROR("Can't set socket send timeout "
538 (long)tv.tv_sec, (int)tv.tv_usec, rc);
543 then = cfs_time_current();
544 rc = -sock_send(C2B_SOCK(sock), &msg,
545 ((timeout == 0) ? MSG_DONTWAIT : 0), &sndlen);
546 to -= cfs_time_current() - then;
548 if (rc != 0 && rc != -EWOULDBLOCK)
555 buffer = ((char *)buffer) + sndlen;
563 libcfs_sock_getaddr (cfs_socket_t *sock, int remote, __u32 *ip, int *port)
565 struct sockaddr_in sin;
569 /* Get remote address */
570 rc = -sock_getpeername(C2B_SOCK(sock), (struct sockaddr *)&sin, sizeof(sin));
572 /* Get local address */
573 rc = -sock_getsockname(C2B_SOCK(sock), (struct sockaddr *)&sin, sizeof(sin));
575 CERROR ("Error %d getting sock %s IP/port\n",
576 rc, remote ? "peer" : "local");
581 *ip = ntohl (sin.sin_addr.s_addr);
584 *port = ntohs (sin.sin_port);
589 libcfs_sock_setbuf (cfs_socket_t *sock, int txbufsize, int rxbufsize)
594 if (txbufsize != 0) {
596 rc = -sock_setsockopt(C2B_SOCK(sock), SOL_SOCKET, SO_SNDBUF,
597 (char *)&option, sizeof (option));
599 CERROR ("Can't set send buffer %d: %d\n",
605 if (rxbufsize != 0) {
607 rc = -sock_setsockopt (C2B_SOCK(sock), SOL_SOCKET, SO_RCVBUF,
608 (char *)&option, sizeof (option));
610 CERROR ("Can't set receive buffer %d: %d\n",
619 libcfs_sock_getbuf (cfs_socket_t *sock, int *txbufsize, int *rxbufsize)
625 if (txbufsize != NULL) {
626 optlen = sizeof(option);
627 rc = -sock_getsockopt(C2B_SOCK(sock), SOL_SOCKET, SO_SNDBUF,
628 (char *)&option, &optlen);
630 CERROR ("Can't get send buffer size: %d\n", rc);
636 if (rxbufsize != NULL) {
637 optlen = sizeof(option);
638 rc = -sock_getsockopt (C2B_SOCK(sock), SOL_SOCKET, SO_RCVBUF,
639 (char *)&option, &optlen);
641 CERROR ("Can't get receive buffer size: %d\n", rc);
650 libcfs_sock_release (cfs_socket_t *sock)
652 if (C2B_SOCK(sock) != NULL) {
653 sock_shutdown(C2B_SOCK(sock), 2);
654 sock_close(C2B_SOCK(sock));
660 libcfs_sock_connect (cfs_socket_t **sockp, int *fatal,
661 __u32 local_ip, int local_port,
662 __u32 peer_ip, int peer_port)
665 struct sockaddr_in srvaddr;
668 rc = libcfs_sock_create(&sock, fatal, local_ip, local_port);
672 bzero(&srvaddr, sizeof(srvaddr));
673 srvaddr.sin_len = sizeof(struct sockaddr_in);
674 srvaddr.sin_family = AF_INET;
675 srvaddr.sin_port = htons(peer_port);
676 srvaddr.sin_addr.s_addr = htonl(peer_ip);
678 rc = -sock_connect(C2B_SOCK(sock), (struct sockaddr *)&srvaddr, 0);
684 *fatal = !(rc == -EADDRNOTAVAIL || rc == -EADDRINUSE);
685 CDEBUG(*fatal ? D_NETERROR : D_NET,
686 "Error %d connecting %u.%u.%u.%u/%d -> %u.%u.%u.%u/%d\n", rc,
687 HIPQUAD(local_ip), local_port, HIPQUAD(peer_ip), peer_port);
689 libcfs_sock_release(sock);
693 #else /* !__DARWIN8__ */
696 * To use bigger buffer for socket:
697 * 1. Increase nmbclusters (Cannot increased by sysctl because it's ready only, so
698 * we must patch kernel).
699 * 2. Increase net.inet.tcp.reass.maxsegments
700 * 3. Increase net.inet.tcp.sendspace
701 * 4. Increase net.inet.tcp.recvspace
702 * 5. Increase kern.ipc.maxsockbuf
704 #define KSOCK_MAX_BUF (1152*1024)
707 libcfs_ipif_query (char *name, int *up, __u32 *ip, __u32 *mask)
714 CFS_DECL_FUNNEL_DATA;
717 rc = socreate(PF_INET, &so, SOCK_STREAM, 0);
720 CERROR ("Can't create socket: %d\n", rc);
723 nob = strnlen(name, IFNAMSIZ);
724 if (nob == IFNAMSIZ) {
725 CERROR("Interface name %s too long\n", name);
730 CLASSERT (sizeof(ifr.ifr_name) >= IFNAMSIZ);
731 strcpy(ifr.ifr_name, name);
733 rc = ifioctl(so, SIOCGIFFLAGS, (caddr_t)&ifr, current_proc());
737 CERROR("Can't get flags for interface %s\n", name);
740 if ((ifr.ifr_flags & IFF_UP) == 0) {
741 CDEBUG(D_NET, "Interface %s down\n", name);
748 strcpy(ifr.ifr_name, name);
749 *((struct sockaddr_in *)&ifr.ifr_addr) = blank_sin();
751 rc = ifioctl(so, SIOCGIFADDR, (caddr_t)&ifr, current_proc());
755 CERROR("Can't get IP address for interface %s\n", name);
759 val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
762 strcpy(ifr.ifr_name, name);
763 *((struct sockaddr_in *)&ifr.ifr_addr) = blank_sin();
765 rc = ifioctl(so, SIOCGIFNETMASK, (caddr_t)&ifr, current_proc());
769 CERROR("Can't get netmask for interface %s\n", name);
773 val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
783 libcfs_ipif_enumerate (char ***namesp)
785 /* Allocate and fill in 'names', returning # interfaces/error */
796 CFS_DECL_FUNNEL_DATA;
799 rc = socreate(PF_INET, &so, SOCK_STREAM, 0);
802 CERROR ("Can't create socket: %d\n", rc);
806 nalloc = 16; /* first guess at max interfaces */
809 if (nalloc * sizeof(*ifr) > CFS_PAGE_SIZE) {
811 nalloc = CFS_PAGE_SIZE/sizeof(*ifr);
812 CWARN("Too many interfaces: only enumerating first %d\n",
816 LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr));
818 CERROR ("ENOMEM enumerating up to %d interfaces\n", nalloc);
823 ifc.ifc_buf = (char *)ifr;
824 ifc.ifc_len = nalloc * sizeof(*ifr);
827 rc = -ifioctl(so, SIOCGIFCONF, (caddr_t)&ifc, current_proc());
831 CERROR ("Error %d enumerating interfaces\n", rc);
835 nfound = ifc.ifc_len/sizeof(*ifr);
836 LASSERT (nfound <= nalloc);
838 if (nfound < nalloc || toobig)
841 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
847 LIBCFS_ALLOC(names, nfound * sizeof(*names));
852 /* NULL out all names[i] */
853 memset (names, 0, nfound * sizeof(*names));
855 for (i = 0; i < nfound; i++) {
857 nob = strnlen (ifr[i].ifr_name, IFNAMSIZ);
858 if (nob == IFNAMSIZ) {
859 /* no space for terminating NULL */
860 CERROR("interface name %.*s too long (%d max)\n",
861 nob, ifr[i].ifr_name, IFNAMSIZ);
866 LIBCFS_ALLOC(names[i], IFNAMSIZ);
867 if (names[i] == NULL) {
872 memcpy(names[i], ifr[i].ifr_name, nob);
881 libcfs_ipif_free_enumeration(names, nfound);
883 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
892 libcfs_sock_create (struct socket **sockp, int *fatal,
893 __u32 local_ip, int local_port)
895 struct sockaddr_in locaddr;
900 CFS_DECL_FUNNEL_DATA;
904 rc = socreate(PF_INET, &so, SOCK_STREAM, 0);
907 CERROR ("Can't create socket: %d\n", rc);
911 bzero(&sopt, sizeof sopt);
913 sopt.sopt_level = SOL_SOCKET;
914 sopt.sopt_name = SO_REUSEADDR;
915 sopt.sopt_val = &option;
916 sopt.sopt_valsize = sizeof(option);
918 rc = sosetopt(so, &sopt);
921 CERROR ("Can't set sock reuse address: %d\n", rc);
924 /* can't specify a local port without a local IP */
925 LASSERT (local_ip == 0 || local_port != 0);
927 if (local_ip != 0 || local_port != 0) {
928 bzero (&locaddr, sizeof (locaddr));
929 locaddr.sin_len = sizeof(struct sockaddr_in);
930 locaddr.sin_family = AF_INET;
931 locaddr.sin_port = htons (local_port);
932 locaddr.sin_addr.s_addr = (local_ip != 0) ? htonl(local_ip) :
935 rc = sobind(so, (struct sockaddr *)&locaddr);
936 if (rc == EADDRINUSE) {
938 CDEBUG(D_NET, "Port %d already in use\n", local_port);
944 CERROR ("Can't bind to local IP Address %u.%u.%u.%u: %d\n",
945 HIPQUAD(local_ip), rc);
959 libcfs_sock_listen (struct socket **sockp,
960 __u32 local_ip, int local_port, int backlog)
964 CFS_DECL_FUNNEL_DATA;
966 rc = libcfs_sock_create(sockp, &fatal, local_ip, local_port);
969 CERROR("Can't create socket: port %d already in use\n",
974 rc = solisten(*sockp, backlog);
978 CERROR("Can't set listen backlog %d: %d\n", backlog, rc);
986 libcfs_sock_accept (struct socket **newsockp, struct socket *sock)
991 CFS_DECL_FUNNEL_DATA;
995 if ((sock->so_options & SO_ACCEPTCONN) == 0) {
1001 if ((sock->so_state & SS_NBIO) && sock->so_comp.tqh_first == NULL) {
1004 return (-EWOULDBLOCK);
1008 while (TAILQ_EMPTY(&sock->so_comp) && sock->so_error == 0) {
1009 if (sock->so_state & SS_CANTRCVMORE) {
1010 sock->so_error = ECONNABORTED;
1013 error = tsleep((caddr_t)&sock->so_timeo, PSOCK | PCATCH,
1021 if (sock->so_error) {
1022 error = sock->so_error;
1030 * At this point we know that there is at least one connection
1031 * ready to be accepted. Remove it from the queue prior to
1032 * allocating the file descriptor for it since falloc() may
1033 * block allowing another process to accept the connection
1036 so = TAILQ_FIRST(&sock->so_comp);
1037 TAILQ_REMOVE(&sock->so_comp, so, so_list);
1040 so->so_state &= ~SS_COMP;
1043 (void) soaccept(so, &sa);
1053 libcfs_sock_abort_accept (struct socket *sock)
1055 wakeup(&sock->so_timeo);
1059 * XXX Liang: timeout for write is not supported yet.
1062 libcfs_sock_write (struct socket *sock, void *buffer, int nob, int timeout)
1068 struct iovec iov = {
1077 .uio_segflg = UIO_SYSSPACE,
1078 .uio_rw = UIO_WRITE,
1083 rc = sosend(sock, NULL, &suio, (struct mbuf *)0, (struct mbuf *)0, 0);
1087 if ( suio.uio_resid != nob && ( rc == ERESTART || rc == EINTR ||\
1092 rc = nob - suio.uio_resid;
1093 buffer = ((char *)buffer) + rc;
1094 nob = suio.uio_resid;
1103 * XXX Liang: timeout for read is not supported yet.
1106 libcfs_sock_read (struct socket *sock, void *buffer, int nob, int timeout)
1112 struct iovec iov = {
1121 .uio_segflg = UIO_SYSSPACE,
1127 rc = soreceive(sock, (struct sockaddr **)0, &ruio, (struct mbuf **)0, (struct mbuf **)0, (int *)0);
1131 if ( ruio.uio_resid != nob && ( rc == ERESTART || rc == EINTR ||\
1136 rc = nob - ruio.uio_resid;
1137 buffer = ((char *)buffer) + rc;
1138 nob = ruio.uio_resid;
1147 libcfs_sock_setbuf (struct socket *sock, int txbufsize, int rxbufsize)
1149 struct sockopt sopt;
1154 bzero(&sopt, sizeof sopt);
1155 sopt.sopt_dir = SOPT_SET;
1156 sopt.sopt_level = SOL_SOCKET;
1157 sopt.sopt_val = &option;
1158 sopt.sopt_valsize = sizeof(option);
1160 if (txbufsize != 0) {
1162 if (option > KSOCK_MAX_BUF)
1163 option = KSOCK_MAX_BUF;
1165 sopt.sopt_name = SO_SNDBUF;
1167 rc = sosetopt(sock, &sopt);
1170 CERROR ("Can't set send buffer %d: %d\n",
1177 if (rxbufsize != 0) {
1179 sopt.sopt_name = SO_RCVBUF;
1181 rc = sosetopt(sock, &sopt);
1184 CERROR ("Can't set receive buffer %d: %d\n",
1193 libcfs_sock_getaddr (struct socket *sock, int remote, __u32 *ip, int *port)
1195 struct sockaddr_in *sin;
1196 struct sockaddr *sa = NULL;
1202 rc = sock->so_proto->pr_usrreqs->pru_peeraddr(sock, &sa);
1206 if (sa) FREE(sa, M_SONAME);
1207 CERROR ("Error %d getting sock peer IP\n", rc);
1212 rc = sock->so_proto->pr_usrreqs->pru_sockaddr(sock, &sa);
1215 if (sa) FREE(sa, M_SONAME);
1216 CERROR ("Error %d getting sock local IP\n", rc);
1221 sin = (struct sockaddr_in *)sa;
1223 *ip = ntohl (sin->sin_addr.s_addr);
1225 *port = ntohs (sin->sin_port);
1233 libcfs_sock_getbuf (struct socket *sock, int *txbufsize, int *rxbufsize)
1235 struct sockopt sopt;
1239 bzero(&sopt, sizeof sopt);
1240 sopt.sopt_dir = SOPT_GET;
1241 sopt.sopt_level = SOL_SOCKET;
1243 if (txbufsize != NULL) {
1244 sopt.sopt_val = txbufsize;
1245 sopt.sopt_valsize = sizeof(*txbufsize);
1246 sopt.sopt_name = SO_SNDBUF;
1248 rc = sogetopt(sock, &sopt);
1251 CERROR ("Can't get send buffer size: %d\n", rc);
1256 if (rxbufsize != NULL) {
1257 sopt.sopt_val = rxbufsize;
1258 sopt.sopt_valsize = sizeof(*rxbufsize);
1259 sopt.sopt_name = SO_RCVBUF;
1261 rc = sogetopt(sock, &sopt);
1264 CERROR ("Can't get receive buffer size: %d\n", rc);
1272 libcfs_sock_connect (struct socket **sockp, int *fatal,
1273 __u32 local_ip, int local_port,
1274 __u32 peer_ip, int peer_port)
1276 struct sockaddr_in srvaddr;
1280 CFS_DECL_FUNNEL_DATA;
1282 rc = libcfs_sock_create(sockp, fatal, local_ip, local_port);
1286 bzero(&srvaddr, sizeof(srvaddr));
1287 srvaddr.sin_len = sizeof(struct sockaddr_in);
1288 srvaddr.sin_family = AF_INET;
1289 srvaddr.sin_port = htons (peer_port);
1290 srvaddr.sin_addr.s_addr = htonl (peer_ip);
1293 rc = soconnect(so, (struct sockaddr *)&srvaddr);
1296 if (rc != EADDRNOTAVAIL && rc != EADDRINUSE)
1298 "Error %d connecting %u.%u.%u.%u/%d -> %u.%u.%u.%u/%d\n", rc,
1299 HIPQUAD(local_ip), local_port, HIPQUAD(peer_ip), peer_port);
1303 while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
1304 CDEBUG(D_NET, "ksocknal sleep for waiting auto_connect.\n");
1305 (void) tsleep((caddr_t)&so->so_timeo, PSOCK, "ksocknal_conn", hz);
1307 if ((rc = so->so_error) != 0) {
1312 "Error %d connecting %u.%u.%u.%u/%d -> %u.%u.%u.%u/%d\n", rc,
1313 HIPQUAD(local_ip), local_port, HIPQUAD(peer_ip), peer_port);
1316 LASSERT(so->so_state & SS_ISCONNECTED);
1331 libcfs_sock_release (struct socket *sock)
1333 CFS_DECL_FUNNEL_DATA;
1335 soshutdown(sock, 0);