source: trunk/libtransmission/net.c @ 12223

Last change on this file since 12223 was 12223, checked in by jordan, 11 years ago

(trunk) copyediting: remove some unneeded #includes, and annotate some needed ones

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