Whamcloud - gitweb
LU-2675 build: remove WinNT "support"
[fs/lustre-release.git] / libcfs / libcfs / user-tcpip.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  */
30 /*
31  * This file is part of Lustre, http://www.lustre.org/
32  * Lustre is a trademark of Sun Microsystems, Inc.
33  */
34
35 #if !defined(__KERNEL__) || !defined(REDSTORM)
36
37 #include <libcfs/libcfs.h>
38
39 #include <sys/socket.h>
40 #ifdef  HAVE_NETINET_IN_H
41 #include <netinet/in.h>
42 #endif
43 #include <netinet/tcp.h>
44 #include <sys/ioctl.h>
45 #include <unistd.h>
46 #include <string.h>
47 #include <unistd.h>
48 #include <poll.h>
49 #include <net/if.h>
50 #include <arpa/inet.h>
51 #include <errno.h>
52 #include <fcntl.h>
53 #if defined(__sun__) || defined(__sun)
54 #include <sys/sockio.h>
55 #endif
56 #include <sys/syscall.h>
57
58 /*
59  * Functions to get network interfaces info
60  */
61
62 int
63 libcfs_sock_ioctl(int cmd, unsigned long arg)
64 {
65         int fd, rc;
66
67         fd = socket(AF_INET, SOCK_STREAM, 0);
68
69         if (fd < 0) {
70                 rc = -errno;
71                 CERROR("socket() failed: errno==%d\n", errno);
72                 return rc;
73         }
74
75         rc = ioctl(fd, cmd, arg);
76
77         close(fd);
78         return rc;
79 }
80
81 int
82 libcfs_ipif_query (char *name, int *up, __u32 *ip)
83 {
84         struct ifreq   ifr;
85         int            nob;
86         int            rc;
87         __u32          val;
88
89         nob = strlen(name);
90         if (nob >= IFNAMSIZ) {
91                 CERROR("Interface name %s too long\n", name);
92                 return -EINVAL;
93         }
94
95         CLASSERT (sizeof(ifr.ifr_name) >= IFNAMSIZ);
96
97         strcpy(ifr.ifr_name, name);
98         rc = libcfs_sock_ioctl(SIOCGIFFLAGS, (unsigned long)&ifr);
99
100         if (rc != 0) {
101                 CERROR("Can't get flags for interface %s\n", name);
102                 return rc;
103         }
104
105         if ((ifr.ifr_flags & IFF_UP) == 0) {
106                 CDEBUG(D_NET, "Interface %s down\n", name);
107                 *up = 0;
108                 *ip = 0;
109                 return 0;
110         }
111
112         *up = 1;
113
114         strcpy(ifr.ifr_name, name);
115         ifr.ifr_addr.sa_family = AF_INET;
116         rc = libcfs_sock_ioctl(SIOCGIFADDR, (unsigned long)&ifr);
117
118         if (rc != 0) {
119                 CERROR("Can't get IP address for interface %s\n", name);
120                 return rc;
121         }
122
123         val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
124         *ip = ntohl(val);
125
126         return 0;
127 }
128
129 void
130 libcfs_ipif_free_enumeration (char **names, int n)
131 {
132         int      i;
133
134         LASSERT (n > 0);
135
136         for (i = 0; i < n && names[i] != NULL; i++)
137                 LIBCFS_FREE(names[i], IFNAMSIZ);
138
139         LIBCFS_FREE(names, n * sizeof(*names));
140 }
141
142 int
143 libcfs_ipif_enumerate (char ***namesp)
144 {
145         /* Allocate and fill in 'names', returning # interfaces/error */
146         char          **names;
147         int             nalloc;
148         int             nfound;
149         struct ifreq   *ifr;
150         struct ifconf   ifc;
151         int             rc;
152         int             nob;
153         int             i;
154
155
156         nalloc = 16;        /* first guess at max interfaces */
157         for (;;) {
158                 LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr));
159                 if (ifr == NULL) {
160                         CERROR ("ENOMEM enumerating up to %d interfaces\n",
161                                 nalloc);
162                         rc = -ENOMEM;
163                         goto out0;
164                 }
165
166                 ifc.ifc_buf = (char *)ifr;
167                 ifc.ifc_len = nalloc * sizeof(*ifr);
168
169                 rc = libcfs_sock_ioctl(SIOCGIFCONF, (unsigned long)&ifc);
170
171                 if (rc < 0) {
172                         CERROR ("Error %d enumerating interfaces\n", rc);
173                         goto out1;
174                 }
175
176                 LASSERT (rc == 0);
177
178                 nfound = ifc.ifc_len/sizeof(*ifr);
179                 LASSERT (nfound <= nalloc);
180
181                 if (nfound < nalloc)
182                         break;
183
184                 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
185                 nalloc *= 2;
186         }
187
188         if (nfound == 0)
189                 goto out1;
190
191         LIBCFS_ALLOC(names, nfound * sizeof(*names));
192         if (names == NULL) {
193                 rc = -ENOMEM;
194                 goto out1;
195         }
196         /* NULL out all names[i] */
197         memset (names, 0, nfound * sizeof(*names));
198
199         for (i = 0; i < nfound; i++) {
200
201                 nob = strlen (ifr[i].ifr_name);
202                 if (nob >= IFNAMSIZ) {
203                         /* no space for terminating NULL */
204                         CERROR("interface name %.*s too long (%d max)\n",
205                                nob, ifr[i].ifr_name, IFNAMSIZ);
206                         rc = -ENAMETOOLONG;
207                         goto out2;
208                 }
209
210                 LIBCFS_ALLOC(names[i], IFNAMSIZ);
211                 if (names[i] == NULL) {
212                         rc = -ENOMEM;
213                         goto out2;
214                 }
215
216                 memcpy(names[i], ifr[i].ifr_name, nob);
217                 names[i][nob] = 0;
218         }
219
220         *namesp = names;
221         rc = nfound;
222
223  out2:
224         if (rc < 0)
225                 libcfs_ipif_free_enumeration(names, nfound);
226  out1:
227         LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
228  out0:
229         return rc;
230 }
231
232 /*
233  * Network functions used by user-land lnet acceptor
234  */
235
236 int
237 libcfs_sock_listen (cfs_socket_t **sockp,
238                     __u32 local_ip, int local_port, int backlog)
239 {
240         int rc;
241         int fatal;
242
243         rc = libcfs_sock_create(sockp, &fatal, local_ip, local_port);
244         if (rc != 0)
245                 return rc;
246
247         if ( listen((*sockp)->s_fd, backlog) ) {
248                 rc = -errno;
249                 CERROR("listen() with backlog==%d failed: errno==%d\n",
250                        backlog, errno);
251                 goto failed;
252         }
253
254         return 0;
255
256   failed:
257         libcfs_sock_release(*sockp);
258         return rc;
259 }
260
261 void
262 libcfs_sock_release (cfs_socket_t *sock)
263 {
264         close(sock->s_fd);
265         LIBCFS_FREE(sock, sizeof(cfs_socket_t));
266 }
267
268 int
269 libcfs_sock_accept (cfs_socket_t **newsockp, cfs_socket_t *sock)
270 {
271         struct sockaddr_in accaddr;
272         socklen_t          accaddr_len = sizeof(struct sockaddr_in);
273
274         LIBCFS_ALLOC(*newsockp, sizeof(cfs_socket_t));
275         if (*newsockp == NULL) {
276                 CERROR ("Can't alloc memory for cfs_socket_t\n");
277                 return -ENOMEM;
278         }
279
280         (*newsockp)->s_fd = accept(sock->s_fd,
281                                    (struct sockaddr *)&accaddr, &accaddr_len);
282
283         if ( (*newsockp)->s_fd < 0 ) {
284                 int rc = -errno;
285                 CERROR("accept() failed: errno==%d\n", -rc);
286                 LIBCFS_FREE(*newsockp, sizeof(cfs_socket_t));
287                 return rc;
288         }
289
290         return 0;
291 }
292
293 int
294 libcfs_sock_read (cfs_socket_t *sock, void *buffer, int nob, int timeout)
295 {
296         int           rc;
297         struct pollfd pfd;
298         cfs_time_t    start_time = cfs_time_current();
299
300         pfd.fd = sock->s_fd;
301         pfd.events = POLLIN;
302         pfd.revents = 0;
303
304         /* poll(2) measures timeout in msec */
305         timeout *= 1000;
306
307         while (nob != 0 && timeout > 0) {
308                 cfs_time_t current_time;
309
310                 rc = poll(&pfd, 1, timeout);
311                 if (rc < 0)
312                         return -errno;
313                 if (rc == 0)
314                         return -ETIMEDOUT;
315                 if ((pfd.revents & POLLIN) == 0)
316                         return -EIO;
317
318                 rc = read(sock->s_fd, buffer, nob);
319                 if (rc < 0)
320                         return -errno;
321                 if (rc == 0)
322                         return -EIO;
323
324                 buffer = ((char *)buffer) + rc;
325                 nob -= rc;
326
327                 current_time = cfs_time_current();
328                 timeout -= 1000 *
329                         cfs_duration_sec(cfs_time_sub(current_time,
330                                                       start_time));
331                 start_time = current_time;
332         }
333
334         if (nob == 0)
335                 return 0;
336         else
337                 return -ETIMEDOUT;
338 }
339
340 int
341 libcfs_sock_write (cfs_socket_t *sock, void *buffer, int nob, int timeout)
342 {
343         int           rc;
344         struct pollfd pfd;
345         cfs_time_t    start_time = cfs_time_current();
346
347         pfd.fd = sock->s_fd;
348         pfd.events = POLLOUT;
349         pfd.revents = 0;
350
351         /* poll(2) measures timeout in msec */
352         timeout *= 1000;
353
354         while (nob != 0 && timeout > 0) {
355                 cfs_time_t current_time;
356
357                 rc = poll(&pfd, 1, timeout);
358                 if (rc < 0)
359                         return -errno;
360                 if (rc == 0)
361                         return -ETIMEDOUT;
362                 if ((pfd.revents & POLLOUT) == 0)
363                         return -EIO;
364
365                 rc = write(sock->s_fd, buffer, nob);
366                 if (rc < 0)
367                         return -errno;
368                 if (rc == 0)
369                         return -EIO;
370
371                 buffer = ((char *)buffer) + rc;
372                 nob -= rc;
373
374                 current_time = cfs_time_current();
375                 timeout -= 1000 *
376                         cfs_duration_sec(cfs_time_sub(current_time,
377                                                       start_time));
378                 start_time = current_time;
379         }
380
381         if (nob == 0)
382                 return 0;
383         else
384                 return -ETIMEDOUT;
385 }
386
387 /* Just try to connect to localhost to wake up entity that are
388  * sleeping in accept() */
389 void
390 libcfs_sock_abort_accept(cfs_socket_t *sock)
391 {
392         int                fd, rc;
393         struct sockaddr_in remaddr;
394         struct sockaddr_in locaddr;
395         socklen_t          alen = sizeof(struct sockaddr_in);
396
397         rc = getsockname(sock->s_fd, (struct sockaddr *)&remaddr, &alen);
398         if ( rc != 0 ) {
399                 CERROR("getsockname() failed: errno==%d\n", errno);
400                 return;
401         }
402
403         memset(&locaddr, 0, sizeof(locaddr));
404         locaddr.sin_family = AF_INET;
405         locaddr.sin_port = remaddr.sin_port;
406         locaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
407
408         fd = socket(AF_INET, SOCK_STREAM, 0);
409         if ( fd < 0 ) {
410                 CERROR("socket() failed: errno==%d\n", errno);
411                 return;
412         }
413
414         rc = connect(fd, (struct sockaddr *)&locaddr, sizeof(locaddr));
415         if ( rc != 0 ) {
416                 if ( errno != ECONNREFUSED )
417                         CERROR("connect() failed: errno==%d\n", errno);
418                 else
419                         CDEBUG(D_NET, "Nobody to wake up at %d\n",
420                                ntohs(remaddr.sin_port));
421         }
422
423         close(fd);
424 }
425
426 int
427 libcfs_sock_getaddr(cfs_socket_t *sock, int remote, __u32 *ip, int *port)
428 {
429         int                rc;
430         struct sockaddr_in peer_addr;
431         socklen_t          peer_addr_len = sizeof(peer_addr);
432
433         LASSERT(remote == 1);
434
435         rc = getpeername(sock->s_fd,
436                          (struct sockaddr *)&peer_addr, &peer_addr_len);
437         if (rc != 0)
438                 return -errno;
439
440         if (ip != NULL)
441                 *ip = ntohl(peer_addr.sin_addr.s_addr);
442         if (port != NULL)
443                 *port = ntohs(peer_addr.sin_port);
444
445         return rc;
446 }
447
448 /*
449  * Network functions of common use
450  */
451
452 int
453 libcfs_socketpair(cfs_socket_t **sockp)
454 {
455         int rc, i, fdp[2];
456
457         LIBCFS_ALLOC(sockp[0], sizeof(cfs_socket_t));
458         if (sockp[0] == NULL) {
459                 CERROR ("Can't alloc memory for cfs_socket_t (1)\n");
460                 return -ENOMEM;
461         }
462
463         LIBCFS_ALLOC(sockp[1], sizeof(cfs_socket_t));
464         if (sockp[1] == NULL) {
465                 CERROR ("Can't alloc memory for cfs_socket_t (2)\n");
466                 LIBCFS_FREE(sockp[0], sizeof(cfs_socket_t));
467                 return -ENOMEM;
468         }
469
470         rc = socketpair(AF_UNIX, SOCK_STREAM, 0, fdp);
471         if (rc != 0) {
472                 rc = -errno;
473                 CERROR ("Cannot create socket pair\n");
474                 LIBCFS_FREE(sockp[0], sizeof(cfs_socket_t));
475                 LIBCFS_FREE(sockp[1], sizeof(cfs_socket_t));
476                 return rc;
477         }
478
479         sockp[0]->s_fd = fdp[0];
480         sockp[1]->s_fd = fdp[1];
481
482         for (i = 0; i < 2; i++) {
483                 rc = libcfs_fcntl_nonblock(sockp[i]);
484                 if (rc) {
485                         libcfs_sock_release(sockp[0]);
486                         libcfs_sock_release(sockp[1]);
487                         return rc;
488                 }
489         }
490
491         return 0;
492 }
493
494 int
495 libcfs_fcntl_nonblock(cfs_socket_t *sock)
496 {
497         int rc, flags;
498
499         flags = fcntl(sock->s_fd, F_GETFL, 0);
500         if (flags == -1) {
501                 rc = -errno;
502                 CERROR ("Cannot get socket flags\n");
503                 return rc;
504         }
505
506         rc = fcntl(sock->s_fd, F_SETFL, flags | O_NONBLOCK);
507         if (rc != 0) {
508                 rc = -errno;
509                 CERROR ("Cannot set socket flags\n");
510                 return rc;
511         }
512
513         return 0;
514 }
515
516 int
517 libcfs_sock_set_nagle(cfs_socket_t *sock, int nagle)
518 {
519         int rc;
520         int option = nagle ? 0 : 1;
521
522         rc = setsockopt(sock->s_fd,
523                         IPPROTO_TCP, TCP_NODELAY, &option, sizeof(option));
524         if (rc != 0) {
525                 rc = -errno;
526                 CERROR ("Cannot set NODELAY socket option\n");
527                 return rc;
528         }
529
530         return 0;
531 }
532
533 int
534 libcfs_sock_set_bufsiz(cfs_socket_t *sock, int bufsiz)
535 {
536         int rc, option;
537
538         LASSERT (bufsiz != 0);
539
540         option = bufsiz;
541         rc = setsockopt(sock->s_fd,
542                         SOL_SOCKET, SO_SNDBUF, &option, sizeof(option));
543         if (rc != 0) {
544                 rc = -errno;
545                 CERROR ("Cannot set SNDBUF socket option\n");
546                 return rc;
547         }
548
549         option = bufsiz;
550         rc = setsockopt(sock->s_fd,
551                         SOL_SOCKET, SO_RCVBUF, &option, sizeof(option));
552         if (rc != 0) {
553                 rc = -errno;
554                 CERROR ("Cannot set RCVBUF socket option\n");
555                 return rc;
556         }
557
558         return 0;
559 }
560
561 int
562 libcfs_sock_bind(cfs_socket_t *sock, __u32 ip, __u16 port)
563 {
564         int                rc;
565         struct sockaddr_in locaddr;
566
567         if (ip == 0 && port == 0)
568                 return 0;
569
570         memset(&locaddr, 0, sizeof(locaddr));
571         locaddr.sin_family = AF_INET;
572         locaddr.sin_addr.s_addr = (ip == 0) ? INADDR_ANY : htonl(ip);
573         locaddr.sin_port = htons(port);
574
575         rc = bind(sock->s_fd, (struct sockaddr *)&locaddr, sizeof(locaddr));
576         if (rc != 0) {
577                 rc = -errno;
578                 CERROR("Cannot bind to %d.%d.%d.%d %d: %d\n",
579                        HIPQUAD(ip), port, rc);
580                 return rc;
581         }
582
583         return 0;
584 }
585
586 int
587 libcfs_sock_create(cfs_socket_t **sockp, int *fatal,
588                    __u32 local_ip, int local_port)
589 {
590         int rc, fd, option;
591
592         *fatal = 1;
593
594         LIBCFS_ALLOC(*sockp, sizeof(cfs_socket_t));
595         if (*sockp == NULL) {
596                 CERROR("Can't alloc memory for cfs_socket_t\n");
597                 return -ENOMEM;
598         }
599
600         fd = socket(AF_INET, SOCK_STREAM, 0);
601         if (fd < 0) {
602                 rc = -errno;
603                 CERROR("Cannot create socket: %d\n", rc);
604                 LIBCFS_FREE(*sockp, sizeof(cfs_socket_t));
605                 return rc;
606         }
607
608         (*sockp)->s_fd = fd;
609
610         option = 1;
611         rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
612                         &option, sizeof(option));
613         if (rc != 0) {
614                 rc = -errno;
615                 CERROR("Cannot set SO_REUSEADDR for socket: %d\n", rc);
616                 libcfs_sock_release(*sockp);
617                 return rc;
618         }
619
620         rc = libcfs_sock_bind(*sockp, local_ip, local_port);
621         if (rc != 0) {
622                 *fatal = 0;
623                 libcfs_sock_release(*sockp);
624         }
625
626         return rc;
627 }
628
629 int
630 libcfs_sock_connect(cfs_socket_t *sock, __u32 ip, __u16 port)
631 {
632         int                rc;
633         struct sockaddr_in addr;
634
635         memset(&addr, 0, sizeof(addr));
636         addr.sin_family      = AF_INET;
637         addr.sin_addr.s_addr = htonl(ip);
638         addr.sin_port        = htons(port);
639
640         rc = connect(sock->s_fd, (struct sockaddr *)&addr,
641                      sizeof(struct sockaddr_in));
642
643         if(rc != 0 && errno != EINPROGRESS) {
644                 rc = -errno;
645                 if (rc != -EADDRINUSE && rc != -EADDRNOTAVAIL)
646                         CERROR ("Cannot connect to %u.%u.%u.%u:%d (err=%d)\n",
647                                 HIPQUAD(ip), port, errno);
648                 return rc;
649         }
650
651         return 0;
652 }
653
654 /* NB: EPIPE and ECONNRESET are considered as non-fatal
655  * because:
656  * 1) it still makes sense to continue reading &&
657  * 2) anyway, poll() will set up POLLHUP|POLLERR flags */
658 int
659 libcfs_sock_writev(cfs_socket_t *sock, const struct iovec *vector, int count)
660 {
661         int rc;
662
663         rc = syscall(SYS_writev, sock->s_fd, vector, count);
664
665         if (rc == 0) /* write nothing */
666                 return 0;
667
668         if (rc < 0) {
669                 if (errno == EAGAIN ||   /* write nothing   */
670                     errno == EPIPE ||    /* non-fatal error */
671                     errno == ECONNRESET) /* non-fatal error */
672                         return 0;
673                 else
674                         return -errno;
675         }
676
677         return rc;
678 }
679
680 int
681 libcfs_sock_readv(cfs_socket_t *sock, const struct iovec *vector, int count)
682 {
683         int rc;
684
685         rc = syscall(SYS_readv, sock->s_fd, vector, count);
686
687         if (rc == 0) /* EOF */
688                 return -EIO;
689
690         if (rc < 0) {
691                 if (errno == EAGAIN) /* read nothing */
692                         return 0;
693                 else
694                         return -errno;
695         }
696
697         return rc;
698 }
699
700 #endif /* !__KERNEL__ || !defined(REDSTORM) */