source: trunk/libtransmission/net.c @ 14482

Last change on this file since 14482 was 14482, checked in by mikedld, 6 years ago

Do not return -EINVAL as socket value (obviously not a good idea).

Also, fix socket descriptor leak in tr_netBindTCPImpl if IPV6_V6ONLY is defined.

  • Property svn:keywords set to Date Rev Author Id
File size: 18.8 KB
Line 
1/******************************************************************************
2 *
3 * $Id: net.c 14482 2015-03-26 18:29:11Z mikedld $
4 *
5 * Copyright (c) Transmission authors and contributors
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 *****************************************************************************/
25
26#include <errno.h>
27#include <string.h>
28#include <assert.h>
29
30#include <sys/types.h>
31
32#ifdef _WIN32
33 #include <ws2tcpip.h>
34#else
35 #include <netinet/tcp.h>       /* TCP_CONGESTION */
36#endif
37
38#include <event2/util.h>
39
40#include <libutp/utp.h>
41
42#include "transmission.h"
43#include "fdlimit.h" /* tr_fdSocketClose () */
44#include "net.h"
45#include "peer-io.h" /* tr_peerIoAddrStr () FIXME this should be moved to net.h */
46#include "session.h" /* tr_sessionGetPublicAddress () */
47#include "tr-utp.h" /* tr_utpSendTo () */
48#include "log.h"
49#include "utils.h" /* tr_time (), tr_logAddDebug () */
50
51#ifndef IN_MULTICAST
52#define IN_MULTICAST(a) (((a) & 0xf0000000) == 0xe0000000)
53#endif
54
55const tr_address tr_in6addr_any = { TR_AF_INET6, { IN6ADDR_ANY_INIT } };
56const tr_address tr_inaddr_any = { TR_AF_INET, { { { { INADDR_ANY, 0x00, 0x00, 0x00 } } } } };
57
58void
59tr_netInit (void)
60{
61    static bool initialized = false;
62
63    if (!initialized)
64    {
65#ifdef _WIN32
66        WSADATA wsaData;
67        WSAStartup (MAKEWORD (2, 2), &wsaData);
68#endif
69        initialized = true;
70    }
71}
72
73char *
74tr_net_strerror (char * buf, size_t buflen, int err)
75{
76    *buf = '\0';
77#ifdef _WIN32
78    FormatMessageA (FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, buf, buflen, NULL);
79#else
80    tr_strlcpy (buf, tr_strerror (err), buflen);
81#endif
82    return buf;
83}
84
85const char *
86tr_address_to_string_with_buf (const tr_address * addr, char * buf, size_t buflen)
87{
88    assert (tr_address_is_valid (addr));
89
90    if (addr->type == TR_AF_INET)
91        return evutil_inet_ntop (AF_INET, &addr->addr, buf, buflen);
92    else
93        return evutil_inet_ntop (AF_INET6, &addr->addr, buf, buflen);
94}
95
96/*
97 * Non-threadsafe version of tr_address_to_string_with_buf ()
98 * and uses a static memory area for a buffer.
99 * This function is suitable to be called from libTransmission's networking code,
100 * which is single-threaded.
101 */
102const char *
103tr_address_to_string (const tr_address * addr)
104{
105    static char buf[INET6_ADDRSTRLEN];
106    return tr_address_to_string_with_buf (addr, buf, sizeof (buf));
107}
108
109bool
110tr_address_from_string (tr_address * dst, const char * src)
111{
112    bool ok;
113
114    if ((ok = evutil_inet_pton (AF_INET, src, &dst->addr) == 1))
115        dst->type = TR_AF_INET;
116
117    if (!ok) /* try IPv6 */
118        if ((ok = evutil_inet_pton (AF_INET6, src, &dst->addr) == 1))
119            dst->type = TR_AF_INET6;
120
121    return ok;
122}
123
124/*
125 * Compare two tr_address structures.
126 * Returns:
127 * <0 if a < b
128 * >0 if a > b
129 * 0  if a == b
130 */
131int
132tr_address_compare (const tr_address * a, const tr_address * b)
133{
134    static const int sizes[2] = { sizeof (struct in_addr), sizeof (struct in6_addr) };
135
136    /* IPv6 addresses are always "greater than" IPv4 */
137    if (a->type != b->type)
138        return a->type == TR_AF_INET ? 1 : -1;
139
140    return memcmp (&a->addr, &b->addr, sizes[a->type]);
141}
142
143/***********************************************************************
144 * TCP sockets
145 **********************************************************************/
146
147int
148tr_netSetTOS (tr_socket_t s,
149              int         tos)
150{
151#ifdef IP_TOS
152    return setsockopt (s, IPPROTO_IP, IP_TOS, (const void *) &tos, sizeof (tos));
153#else
154    return 0;
155#endif
156}
157
158int
159tr_netSetCongestionControl (tr_socket_t   s UNUSED,
160                            const char  * algorithm UNUSED)
161{
162#ifdef TCP_CONGESTION
163    return setsockopt (s, IPPROTO_TCP, TCP_CONGESTION,
164                       (const void *) algorithm, strlen (algorithm) + 1);
165#else
166    errno = ENOSYS;
167    return -1;
168#endif
169}
170
171bool
172tr_address_from_sockaddr_storage (tr_address                     * setme_addr,
173                                  tr_port                        * setme_port,
174                                  const struct sockaddr_storage  * from)
175{
176    if (from->ss_family == AF_INET)
177    {
178        struct sockaddr_in * sin = (struct sockaddr_in *)from;
179        setme_addr->type = TR_AF_INET;
180        setme_addr->addr.addr4.s_addr = sin->sin_addr.s_addr;
181        *setme_port = sin->sin_port;
182        return true;
183    }
184
185    if (from->ss_family == AF_INET6)
186    {
187        struct sockaddr_in6 *sin6 = (struct sockaddr_in6*) from;
188        setme_addr->type = TR_AF_INET6;
189        setme_addr->addr.addr6 = sin6->sin6_addr;
190        *setme_port = sin6->sin6_port;
191        return true;
192    }
193
194    return false;
195}
196
197static socklen_t
198setup_sockaddr (const tr_address        * addr,
199                tr_port                   port,
200                struct sockaddr_storage * sockaddr)
201{
202    assert (tr_address_is_valid (addr));
203
204    if (addr->type == TR_AF_INET)
205    {
206        struct sockaddr_in  sock4;
207        memset (&sock4, 0, sizeof (sock4));
208        sock4.sin_family      = AF_INET;
209        sock4.sin_addr.s_addr = addr->addr.addr4.s_addr;
210        sock4.sin_port        = port;
211        memcpy (sockaddr, &sock4, sizeof (sock4));
212        return sizeof (struct sockaddr_in);
213    }
214    else
215    {
216        struct sockaddr_in6 sock6;
217        memset (&sock6, 0, sizeof (sock6));
218        sock6.sin6_family   = AF_INET6;
219        sock6.sin6_port     = port;
220        sock6.sin6_flowinfo = 0;
221        sock6.sin6_addr     = addr->addr.addr6;
222        memcpy (sockaddr, &sock6, sizeof (sock6));
223        return sizeof (struct sockaddr_in6);
224    }
225}
226
227tr_socket_t
228tr_netOpenPeerSocket (tr_session        * session,
229                      const tr_address  * addr,
230                      tr_port             port,
231                      bool                clientIsSeed)
232{
233    static const int domains[NUM_TR_AF_INET_TYPES] = { AF_INET, AF_INET6 };
234    tr_socket_t             s;
235    struct sockaddr_storage sock;
236    socklen_t               addrlen;
237    const tr_address      * source_addr;
238    socklen_t               sourcelen;
239    struct sockaddr_storage source_sock;
240
241    assert (tr_address_is_valid (addr));
242
243    if (!tr_address_is_valid_for_peers (addr, port))
244        return TR_BAD_SOCKET; /* -EINVAL */
245
246    s = tr_fdSocketCreate (session, domains[addr->type], SOCK_STREAM);
247    if (s == TR_BAD_SOCKET)
248        return TR_BAD_SOCKET;
249
250    /* seeds don't need much of a read buffer... */
251    if (clientIsSeed) {
252        int n = 8192;
253        if (setsockopt (s, SOL_SOCKET, SO_RCVBUF, (const void *) &n, sizeof (n)))
254            tr_logAddInfo ("Unable to set SO_RCVBUF on socket %"TR_PRI_SOCK": %s", s, tr_strerror (sockerrno));
255    }
256
257    if (evutil_make_socket_nonblocking (s) < 0) {
258        tr_netClose (session, s);
259        return TR_BAD_SOCKET;
260    }
261
262    addrlen = setup_sockaddr (addr, port, &sock);
263
264    /* set source address */
265    source_addr = tr_sessionGetPublicAddress (session, addr->type, NULL);
266    assert (source_addr);
267    sourcelen = setup_sockaddr (source_addr, 0, &source_sock);
268    if (bind (s, (struct sockaddr *) &source_sock, sourcelen))
269    {
270        tr_logAddError (_("Couldn't set source address %s on %"TR_PRI_SOCK": %s"),
271                tr_address_to_string (source_addr), s, tr_strerror (errno));
272        tr_netClose (session, s);
273        return TR_BAD_SOCKET; /* -errno */
274    }
275
276    if ((connect (s, (struct sockaddr *) &sock,
277                  addrlen) < 0)
278#ifdef _WIN32
279      && (sockerrno != WSAEWOULDBLOCK)
280#endif
281      && (sockerrno != EINPROGRESS))
282    {
283        int tmperrno;
284        tmperrno = sockerrno;
285        if ((tmperrno != ENETUNREACH && tmperrno != EHOSTUNREACH)
286                || addr->type == TR_AF_INET)
287            tr_logAddError (_("Couldn't connect socket %"TR_PRI_SOCK" to %s, port %d (errno %d - %s)"),
288                    s, tr_address_to_string (addr), (int)ntohs (port), tmperrno,
289                    tr_strerror (tmperrno));
290        tr_netClose (session, s);
291        s = TR_BAD_SOCKET; /* -tmperrno */
292    }
293
294    tr_logAddDeep (__FILE__, __LINE__, NULL, "New OUTGOING connection %"TR_PRI_SOCK" (%s)",
295                   s, tr_peerIoAddrStr (addr, port));
296
297    return s;
298}
299
300struct UTPSocket *
301tr_netOpenPeerUTPSocket (tr_session        * session,
302                         const tr_address  * addr,
303                         tr_port             port,
304                         bool                clientIsSeed UNUSED)
305{
306  struct UTPSocket * ret = NULL;
307
308  if (tr_address_is_valid_for_peers (addr, port))
309    {
310      struct sockaddr_storage ss;
311      const socklen_t sslen = setup_sockaddr (addr, port, &ss);
312      ret = UTP_Create (tr_utpSendTo, session, (struct sockaddr*)&ss, sslen);
313    }
314
315  return ret;
316}
317
318static tr_socket_t
319tr_netBindTCPImpl (const tr_address * addr,
320                   tr_port            port,
321                   bool               suppressMsgs,
322                   int              * errOut)
323{
324    static const int domains[NUM_TR_AF_INET_TYPES] = { AF_INET, AF_INET6 };
325    struct sockaddr_storage sock;
326    tr_socket_t fd;
327    int addrlen;
328    int optval;
329
330    assert (tr_address_is_valid (addr));
331
332    fd = socket (domains[addr->type], SOCK_STREAM, 0);
333    if (fd == TR_BAD_SOCKET) {
334        *errOut = sockerrno;
335        return TR_BAD_SOCKET;
336    }
337
338    if (evutil_make_socket_nonblocking (fd) < 0) {
339        *errOut = sockerrno;
340        tr_netCloseSocket (fd);
341        return TR_BAD_SOCKET;
342    }
343
344    optval = 1;
345    setsockopt (fd, SOL_SOCKET, SO_KEEPALIVE, (const void *) &optval, sizeof (optval));
346    setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (const void *) &optval, sizeof (optval));
347
348#ifdef IPV6_V6ONLY
349    if (addr->type == TR_AF_INET6)
350        if (setsockopt (fd, IPPROTO_IPV6, IPV6_V6ONLY, (const void *) &optval, sizeof (optval)) == -1)
351            if (sockerrno != ENOPROTOOPT) { /* if the kernel doesn't support it, ignore it */
352                *errOut = sockerrno;
353                tr_netCloseSocket (fd);
354                return TR_BAD_SOCKET;
355            }
356#endif
357
358    addrlen = setup_sockaddr (addr, htons (port), &sock);
359    if (bind (fd, (struct sockaddr *) &sock, addrlen)) {
360        const int err = sockerrno;
361        if (!suppressMsgs)
362        {
363            const char * fmt;
364            const char * hint;
365
366            if (err == EADDRINUSE)
367                hint = _("Is another copy of Transmission already running?");
368            else
369                hint = NULL;
370
371            if (hint == NULL)
372                fmt = _("Couldn't bind port %d on %s: %s");
373            else
374                fmt = _("Couldn't bind port %d on %s: %s (%s)");
375
376            tr_logAddError (fmt, port, tr_address_to_string (addr), tr_strerror (err), hint);
377        }
378        tr_netCloseSocket (fd);
379        *errOut = err;
380        return TR_BAD_SOCKET;
381    }
382
383    if (!suppressMsgs)
384        tr_logAddDebug ("Bound socket %"TR_PRI_SOCK" to port %d on %s", fd, port, tr_address_to_string (addr));
385
386    if (listen (fd, 128) == -1) {
387        *errOut = sockerrno;
388        tr_netCloseSocket (fd);
389        return TR_BAD_SOCKET;
390    }
391
392    return fd;
393}
394
395tr_socket_t
396tr_netBindTCP (const tr_address * addr,
397               tr_port            port,
398               bool               suppressMsgs)
399{
400    int unused;
401    return tr_netBindTCPImpl (addr, port, suppressMsgs, &unused);
402}
403
404bool
405tr_net_hasIPv6 (tr_port port)
406{
407    static bool result = false;
408    static bool alreadyDone = false;
409
410    if (!alreadyDone)
411    {
412        int err;
413        tr_socket_t fd = tr_netBindTCPImpl (&tr_in6addr_any, port, true, &err);
414        if (fd != TR_BAD_SOCKET || err != EAFNOSUPPORT) /* we support ipv6 */
415            result = true;
416        if (fd != TR_BAD_SOCKET)
417            tr_netCloseSocket (fd);
418        alreadyDone = true;
419    }
420
421    return result;
422}
423
424tr_socket_t
425tr_netAccept (tr_session  * session,
426              tr_socket_t   b,
427              tr_address  * addr,
428              tr_port     * port)
429{
430    tr_socket_t fd = tr_fdSocketAccept (session, b, addr, port);
431
432    if (fd != TR_BAD_SOCKET && evutil_make_socket_nonblocking (fd) < 0) {
433        tr_netClose (session, fd);
434        fd = TR_BAD_SOCKET;
435    }
436
437    return fd;
438}
439
440void
441tr_netCloseSocket (tr_socket_t fd)
442{
443    evutil_closesocket (fd);
444}
445
446void
447tr_netClose (tr_session  * session,
448             tr_socket_t   s)
449{
450    tr_fdSocketClose (session, s);
451}
452
453/*
454   get_source_address () and global_unicast_address () were written by
455   Juliusz Chroboczek, and are covered under the same license as dht.c.
456   Please feel free to copy them into your software if it can help
457   unbreaking the double-stack Internet. */
458
459/* Get the source address used for a given destination address. Since
460   there is no official interface to get this information, we create
461   a connected UDP socket (connected UDP... hmm...) and check its source
462   address. */
463static int
464get_source_address (const struct sockaddr  * dst,
465                    socklen_t                dst_len,
466                    struct sockaddr        * src,
467                    socklen_t              * src_len)
468{
469    tr_socket_t s;
470    int rc, save;
471
472    s = socket (dst->sa_family, SOCK_DGRAM, 0);
473    if (s == TR_BAD_SOCKET)
474        goto fail;
475
476    /* Since it's a UDP socket, this doesn't actually send any packets. */
477    rc = connect (s, dst, dst_len);
478    if (rc < 0)
479        goto fail;
480
481    rc = getsockname (s, src, src_len);
482    if (rc < 0)
483        goto fail;
484
485    evutil_closesocket (s);
486
487    return rc;
488
489 fail:
490    save = errno;
491    evutil_closesocket (s);
492    errno = save;
493    return -1;
494}
495
496/* We all hate NATs. */
497static int
498global_unicast_address (struct sockaddr *sa)
499{
500    if (sa->sa_family == AF_INET) {
501        const unsigned char *a =
502          (unsigned char*)& ((struct sockaddr_in*)sa)->sin_addr;
503        if (a[0] == 0 || a[0] == 127 || a[0] >= 224 ||
504           a[0] == 10 || (a[0] == 172 && a[1] >= 16 && a[1] <= 31) ||
505         (a[0] == 192 && a[1] == 168))
506            return 0;
507        return 1;
508    } else if (sa->sa_family == AF_INET6) {
509        const unsigned char *a =
510          (unsigned char*)& ((struct sockaddr_in6*)sa)->sin6_addr;
511        /* 2000::/3 */
512        return (a[0] & 0xE0) == 0x20;
513    } else {
514        errno = EAFNOSUPPORT;
515        return -1;
516    }
517}
518
519static int
520tr_globalAddress (int af, void *addr, int *addr_len)
521{
522    struct sockaddr_storage ss;
523    socklen_t sslen = sizeof (ss);
524    struct sockaddr_in sin;
525    struct sockaddr_in6 sin6;
526    struct sockaddr *sa;
527    socklen_t salen;
528    int rc;
529
530    switch (af) {
531    case AF_INET:
532        memset (&sin, 0, sizeof (sin));
533        sin.sin_family = AF_INET;
534        evutil_inet_pton (AF_INET, "91.121.74.28", &sin.sin_addr);
535        sin.sin_port = htons (6969);
536        sa = (struct sockaddr*)&sin;
537        salen = sizeof (sin);
538        break;
539    case AF_INET6:
540        memset (&sin6, 0, sizeof (sin6));
541        sin6.sin6_family = AF_INET6;
542        /* In order for address selection to work right, this should be
543           a native IPv6 address, not Teredo or 6to4. */
544        evutil_inet_pton (AF_INET6, "2001:1890:1112:1::20", &sin6.sin6_addr);
545        sin6.sin6_port = htons (6969);
546        sa = (struct sockaddr*)&sin6;
547        salen = sizeof (sin6);
548        break;
549    default:
550        return -1;
551    }
552
553    rc = get_source_address (sa, salen, (struct sockaddr*)&ss, &sslen);
554
555    if (rc < 0)
556        return -1;
557
558    if (!global_unicast_address ((struct sockaddr*)&ss))
559        return -1;
560
561    switch (af) {
562    case AF_INET:
563        if (*addr_len < 4)
564            return -1;
565        memcpy (addr, & ((struct sockaddr_in*)&ss)->sin_addr, 4);
566        *addr_len = 4;
567        return 1;
568    case AF_INET6:
569        if (*addr_len < 16)
570            return -1;
571        memcpy (addr, & ((struct sockaddr_in6*)&ss)->sin6_addr, 16);
572        *addr_len = 16;
573        return 1;
574    default:
575        return -1;
576    }
577}
578
579/* Return our global IPv6 address, with caching. */
580
581const unsigned char *
582tr_globalIPv6 (void)
583{
584    static unsigned char ipv6[16];
585    static time_t last_time = 0;
586    static bool have_ipv6 = false;
587    const time_t now = tr_time ();
588
589    /* Re-check every half hour */
590    if (last_time < now - 1800)
591    {
592        int addrlen = 16;
593        const int rc = tr_globalAddress (AF_INET6, ipv6, &addrlen);
594        have_ipv6 = (rc >= 0) && (addrlen == 16);
595        last_time = now;
596    }
597
598    return have_ipv6 ? ipv6 : NULL;
599}
600
601/***
602****
603****
604***/
605
606static bool
607isIPv4MappedAddress (const tr_address * addr)
608{
609    return (addr->type == TR_AF_INET6) && IN6_IS_ADDR_V4MAPPED (&addr->addr.addr6);
610}
611
612static bool
613isIPv6LinkLocalAddress (const tr_address * addr)
614{
615    return ((addr->type == TR_AF_INET6)
616                  && IN6_IS_ADDR_LINKLOCAL (&addr->addr.addr6));
617}
618
619/* isMartianAddr was written by Juliusz Chroboczek,
620   and is covered under the same license as third-party/dht/dht.c. */
621static bool
622isMartianAddr (const struct tr_address * a)
623{
624    static const unsigned char zeroes[16] =
625        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
626
627    assert (tr_address_is_valid (a));
628
629    switch (a->type)
630    {
631        case TR_AF_INET: {
632            const unsigned char * address = (const unsigned char*)&a->addr.addr4;
633            return (address[0] == 0) ||
634                 (address[0] == 127) ||
635                 ((address[0] & 0xE0) == 0xE0);
636            break;
637        }
638
639        case TR_AF_INET6: {
640            const unsigned char * address = (const unsigned char*)&a->addr.addr6;
641            return (address[0] == 0xFF) ||
642                 (memcmp (address, zeroes, 15) == 0 &&
643                  (address[15] == 0 || address[15] == 1)) ||
644                   /* Addresses outside of 2000::/3 are currently reserved,
645                      but might be allocated at some future time. Since
646                      there are a lot of buggy peers pushing around such
647                      addresses over PEX, we reject them until the end of
648                      the 13th Baktun. */
649                 (tr_time () < 1356130800 && (address[0] & 0xE0) != 0x20);
650            break;
651        }
652
653        default:
654            return true;
655    }
656}
657
658bool
659tr_address_is_valid_for_peers (const tr_address * addr, tr_port port)
660{
661    return (port != 0)
662        && (tr_address_is_valid (addr))
663        && (!isIPv6LinkLocalAddress (addr))
664        && (!isIPv4MappedAddress (addr))
665        && (!isMartianAddr (addr));
666}
Note: See TracBrowser for help on using the repository browser.