source: trunk/libtransmission/net.c @ 10111

Last change on this file since 10111 was 10111, checked in by charles, 12 years ago

(trunk libT) when we can't bind to a port and the error is EADDRINUSE, add a parenthetical hint "(Is another copy of Transmission already running?)"

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