source: trunk/libtransmission/net.c @ 11960

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

add configure script switch to enable/disable utp

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