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