1 /******************************************************************************
3 * $Id: net.c 11494 2010-12-08 17:22:00Z charles $
5 * Copyright (c) 2005-2008 Transmission authors and contributors
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:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
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 *****************************************************************************/
32 #include <sys/types.h>
35 #define _WIN32_WINNT 0x0501
38 #include <sys/socket.h>
39 #include <netinet/in.h>
40 #include <netinet/tcp.h>
41 #include <arpa/inet.h> /* inet_addr */
47 #include <stdarg.h> /* some 1.4.x versions of evutil.h need this */
50 #include "transmission.h"
60 #define IN_MULTICAST( a ) ( ( ( a ) & 0xf0000000 ) == 0xe0000000 )
63 const tr_address tr_in6addr_any
= { TR_AF_INET6
, { IN6ADDR_ANY_INIT
} };
64 const tr_address tr_inaddr_any
= { TR_AF_INET
, { { { { INADDR_ANY
, 0x00, 0x00, 0x00 } } } } };
68 inet_ntop( int af
, const void * src
, char * dst
, socklen_t cnt
)
72 struct sockaddr_in in
;
73 memset( &in
, 0, sizeof( in
) );
74 in
.sin_family
= AF_INET
;
75 memcpy( &in
.sin_addr
, src
, sizeof( struct in_addr
) );
76 getnameinfo((struct sockaddr
*)&in
, sizeof(struct sockaddr_in
),
77 dst
, cnt
, NULL
, 0, NI_NUMERICHOST
);
80 else if (af
== AF_INET6
)
82 struct sockaddr_in6 in
;
83 memset( &in
, 0, sizeof( in
) );
84 in
.sin6_family
= AF_INET6
;
85 memcpy( &in
.sin6_addr
, src
, sizeof( struct in_addr6
) );
86 getnameinfo((struct sockaddr
*)&in
, sizeof(struct sockaddr_in6
),
87 dst
, cnt
, NULL
, 0, NI_NUMERICHOST
);
94 inet_pton( int af
, const char * src
, void * dst
)
96 struct addrinfo hints
, *res
, *ressave
;
97 struct sockaddr_in
* s4
;
98 struct sockaddr_in6
* s6
;
100 memset( &hints
, 0, sizeof( struct addrinfo
));
101 hints
.ai_family
= af
;
102 hints
.ai_flags
= AI_NUMERICHOST
;
104 if( getaddrinfo( src
, NULL
, &hints
, &res
) ) {
105 if( WSAGetLastError() == WSAHOST_NOT_FOUND
)
108 errno
= EAFNOSUPPORT
;
115 switch (res
->ai_family
) {
117 s4
= (struct sockaddr_in
*) res
->ai_addr
;
118 memcpy( dst
, &s4
->sin_addr
, sizeof( struct in_addr
) );
121 s6
= (struct sockaddr_in6
*) res
->ai_addr
;
122 memcpy( dst
, &s6
->sin6_addr
, sizeof( struct in6_addr
) );
124 default: /* AF_UNSPEC, AF_NETBIOS */
130 freeaddrinfo(ressave
);
138 static int initialized
= FALSE
;
144 WSAStartup( MAKEWORD( 2, 2 ), &wsaData
);
151 tr_net_strerror( char * buf
, size_t buflen
, int err
)
155 FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, err
, 0, buf
, buflen
, NULL
);
157 tr_strlcpy( buf
, tr_strerror( err
), buflen
);
163 tr_ntop( const tr_address
* src
, char * dst
, int size
)
165 assert( tr_isAddress( src
) );
167 if( src
->type
== TR_AF_INET
)
168 return inet_ntop( AF_INET
, &src
->addr
, dst
, size
);
170 return inet_ntop( AF_INET6
, &src
->addr
, dst
, size
);
174 * Non-threadsafe version of tr_ntop, which uses a static memory area for a buffer.
175 * This function is suitable to be called from libTransmission's networking code,
176 * which is single-threaded.
179 tr_ntop_non_ts( const tr_address
* src
)
181 static char buf
[INET6_ADDRSTRLEN
];
182 return tr_ntop( src
, buf
, sizeof( buf
) );
186 tr_pton( const char * src
, tr_address
* dst
)
188 int retval
= inet_pton( AF_INET
, src
, &dst
->addr
);
192 else if( retval
== 0 )
193 retval
= inet_pton( AF_INET6
, src
, &dst
->addr
);
196 dst
->type
= TR_AF_INET
;
202 dst
->type
= TR_AF_INET6
;
207 * Compare two tr_address structures.
214 tr_compareAddresses( const tr_address
* a
, const tr_address
* b
)
216 static const int sizes
[2] = { sizeof(struct in_addr
), sizeof(struct in6_addr
) };
218 /* IPv6 addresses are always "greater than" IPv4 */
219 if( a
->type
!= b
->type
)
220 return a
->type
== TR_AF_INET
? 1 : -1;
222 return memcmp( &a
->addr
, &b
->addr
, sizes
[a
->type
] );
225 /***********************************************************************
227 **********************************************************************/
230 tr_netSetTOS( int s
, int tos
)
233 return setsockopt( s
, IPPROTO_IP
, IP_TOS
, (char*)&tos
, sizeof( tos
) );
240 tr_netSetCongestionControl( int s UNUSED
, const char *algorithm UNUSED
)
242 #ifdef TCP_CONGESTION
243 return setsockopt( s
, IPPROTO_TCP
, TCP_CONGESTION
,
244 algorithm
, strlen(algorithm
) + 1 );
252 setup_sockaddr( const tr_address
* addr
,
254 struct sockaddr_storage
* sockaddr
)
256 assert( tr_isAddress( addr
) );
258 if( addr
->type
== TR_AF_INET
)
260 struct sockaddr_in sock4
;
261 memset( &sock4
, 0, sizeof( sock4
) );
262 sock4
.sin_family
= AF_INET
;
263 sock4
.sin_addr
.s_addr
= addr
->addr
.addr4
.s_addr
;
264 sock4
.sin_port
= port
;
265 memcpy( sockaddr
, &sock4
, sizeof( sock4
) );
266 return sizeof( struct sockaddr_in
);
270 struct sockaddr_in6 sock6
;
271 memset( &sock6
, 0, sizeof( sock6
) );
272 sock6
.sin6_family
= AF_INET6
;
273 sock6
.sin6_port
= port
;
274 sock6
.sin6_flowinfo
= 0;
275 sock6
.sin6_addr
= addr
->addr
.addr6
;
276 memcpy( sockaddr
, &sock6
, sizeof( sock6
) );
277 return sizeof( struct sockaddr_in6
);
282 tr_netOpenPeerSocket( tr_session
* session
,
283 const tr_address
* addr
,
285 tr_bool clientIsSeed
)
287 static const int domains
[NUM_TR_AF_INET_TYPES
] = { AF_INET
, AF_INET6
};
289 struct sockaddr_storage sock
;
291 const tr_address
* source_addr
;
293 struct sockaddr_storage source_sock
;
295 assert( tr_isAddress( addr
) );
297 if( !tr_isValidPeerAddress( addr
, port
) )
300 s
= tr_fdSocketCreate( session
, domains
[addr
->type
], SOCK_STREAM
);
304 /* seeds don't need much of a read buffer... */
307 if( setsockopt( s
, SOL_SOCKET
, SO_RCVBUF
, &n
, sizeof(n
) ) )
308 tr_inf( "Unable to set SO_RCVBUF on socket %d: %s", s
, tr_strerror( sockerrno
) );
311 if( evutil_make_socket_nonblocking( s
) < 0 ) {
312 tr_netClose( session
, s
);
316 addrlen
= setup_sockaddr( addr
, port
, &sock
);
318 /* set source address */
319 source_addr
= tr_sessionGetPublicAddress( session
, addr
->type
);
320 assert( source_addr
);
321 sourcelen
= setup_sockaddr( source_addr
, 0, &source_sock
);
322 if( bind( s
, ( struct sockaddr
* ) &source_sock
, sourcelen
) )
324 tr_err( _( "Couldn't set source address %s on %d: %s" ),
325 tr_ntop_non_ts( source_addr
), s
, tr_strerror( errno
) );
329 if( ( connect( s
, (struct sockaddr
*) &sock
,
332 && ( sockerrno
!= WSAEWOULDBLOCK
)
334 && ( sockerrno
!= EINPROGRESS
) )
337 tmperrno
= sockerrno
;
338 if( ( tmperrno
!= ENETUNREACH
&& tmperrno
!= EHOSTUNREACH
)
339 || addr
->type
== TR_AF_INET
)
340 tr_err( _( "Couldn't connect socket %d to %s, port %d (errno %d - %s)" ),
341 s
, tr_ntop_non_ts( addr
), (int)ntohs( port
), tmperrno
,
342 tr_strerror( tmperrno
) );
343 tr_netClose( session
, s
);
347 tr_deepLog( __FILE__
, __LINE__
, NULL
, "New OUTGOING connection %d (%s)",
348 s
, tr_peerIoAddrStr( addr
, port
) );
354 tr_netBindTCPImpl( const tr_address
* addr
, tr_port port
, tr_bool suppressMsgs
, int * errOut
)
356 static const int domains
[NUM_TR_AF_INET_TYPES
] = { AF_INET
, AF_INET6
};
357 struct sockaddr_storage sock
;
362 assert( tr_isAddress( addr
) );
364 fd
= socket( domains
[addr
->type
], SOCK_STREAM
, 0 );
370 if( evutil_make_socket_nonblocking( fd
) < 0 ) {
372 tr_netCloseSocket( fd
);
377 setsockopt( fd
, SOL_SOCKET
, SO_KEEPALIVE
, &optval
, sizeof(optval
) );
378 setsockopt( fd
, SOL_SOCKET
, SO_REUSEADDR
, &optval
, sizeof(optval
) );
381 if( addr
->type
== TR_AF_INET6
)
382 if( setsockopt( fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &optval
, sizeof( optval
) ) == -1 )
383 if( sockerrno
!= ENOPROTOOPT
) { /* if the kernel doesn't support it, ignore it */
389 addrlen
= setup_sockaddr( addr
, htons( port
), &sock
);
390 if( bind( fd
, (struct sockaddr
*) &sock
, addrlen
) ) {
391 const int err
= sockerrno
;
397 if( err
== EADDRINUSE
)
398 hint
= _( "Is another copy of Transmission already running?" );
403 fmt
= _( "Couldn't bind port %d on %s: %s" );
405 fmt
= _( "Couldn't bind port %d on %s: %s (%s)" );
407 tr_err( fmt
, port
, tr_ntop_non_ts( addr
), tr_strerror( err
), hint
);
409 tr_netCloseSocket( fd
);
415 tr_dbg( "Bound socket %d to port %d on %s", fd
, port
, tr_ntop_non_ts( addr
) );
417 if( listen( fd
, 128 ) == -1 ) {
419 tr_netCloseSocket( fd
);
427 tr_netBindTCP( const tr_address
* addr
, tr_port port
, tr_bool suppressMsgs
)
430 return tr_netBindTCPImpl( addr
, port
, suppressMsgs
, &unused
);
434 tr_net_hasIPv6( tr_port port
)
436 static tr_bool result
= FALSE
;
437 static tr_bool alreadyDone
= FALSE
;
442 int fd
= tr_netBindTCPImpl( &tr_in6addr_any
, port
, TRUE
, &err
);
443 if( fd
>= 0 || err
!= EAFNOSUPPORT
) /* we support ipv6 */
446 tr_netCloseSocket( fd
);
454 tr_netAccept( tr_session
* session
,
459 int fd
= tr_fdSocketAccept( session
, b
, addr
, port
);
461 if( fd
>=0 && evutil_make_socket_nonblocking(fd
)<0 ) {
462 tr_netClose( session
, fd
);
470 tr_netCloseSocket( int fd
)
472 EVUTIL_CLOSESOCKET( fd
);
476 tr_netClose( tr_session
* session
, int s
)
478 tr_fdSocketClose( session
, s
);
482 get_source_address() and global_unicast_address() were written by
483 Juliusz Chroboczek, and are covered under the same license as dht.c.
484 Please feel free to copy them into your software if it can help
485 unbreaking the double-stack Internet. */
487 /* Get the source address used for a given destination address. Since
488 there is no official interface to get this information, we create
489 a connected UDP socket (connected UDP... hmm...) and check its source
492 get_source_address( const struct sockaddr
* dst
,
494 struct sockaddr
* src
,
495 socklen_t
* src_len
)
499 s
= socket(dst
->sa_family
, SOCK_DGRAM
, 0);
503 /* Since it's a UDP socket, this doesn't actually send any packets. */
504 rc
= connect(s
, dst
, dst_len
);
508 rc
= getsockname(s
, src
, src_len
);
512 EVUTIL_CLOSESOCKET( s
);
518 EVUTIL_CLOSESOCKET( s
);
523 /* We all hate NATs. */
525 global_unicast_address(struct sockaddr
*sa
)
527 if(sa
->sa_family
== AF_INET
) {
528 const unsigned char *a
=
529 (unsigned char*)&((struct sockaddr_in
*)sa
)->sin_addr
;
530 if(a
[0] == 0 || a
[0] == 127 || a
[0] >= 224 ||
531 a
[0] == 10 || (a
[0] == 172 && a
[1] >= 16 && a
[1] <= 31) ||
532 (a
[0] == 192 && a
[1] == 168))
535 } else if(sa
->sa_family
== AF_INET6
) {
536 const unsigned char *a
=
537 (unsigned char*)&((struct sockaddr_in6
*)sa
)->sin6_addr
;
539 return (a
[0] & 0xE0) == 0x20;
541 errno
= EAFNOSUPPORT
;
547 tr_globalAddress( int af
, void *addr
, int *addr_len
)
549 struct sockaddr_storage ss
;
550 socklen_t sslen
= sizeof(ss
);
551 struct sockaddr_in sin
;
552 struct sockaddr_in6 sin6
;
559 memset(&sin
, 0, sizeof(sin
));
560 sin
.sin_family
= AF_INET
;
561 inet_pton(AF_INET
, "91.121.74.28", &sin
.sin_addr
);
562 sin
.sin_port
= htons(6969);
563 sa
= (struct sockaddr
*)&sin
;
567 memset(&sin6
, 0, sizeof(sin6
));
568 sin6
.sin6_family
= AF_INET6
;
569 /* In order for address selection to work right, this should be
570 a native IPv6 address, not Teredo or 6to4. */
571 inet_pton(AF_INET6
, "2001:1890:1112:1::20", &sin6
.sin6_addr
);
572 sin6
.sin6_port
= htons(6969);
573 sa
= (struct sockaddr
*)&sin6
;
574 salen
= sizeof(sin6
);
580 rc
= get_source_address( sa
, salen
, (struct sockaddr
*)&ss
, &sslen
);
585 if( !global_unicast_address( (struct sockaddr
*)&ss
) )
592 memcpy(addr
, &((struct sockaddr_in
*)&ss
)->sin_addr
, 4);
598 memcpy(addr
, &((struct sockaddr_in6
*)&ss
)->sin6_addr
, 16);
606 /* Return our global IPv6 address, with caching. */
608 const unsigned char *
609 tr_globalIPv6( void )
611 static unsigned char ipv6
[16];
612 static time_t last_time
= 0;
613 static int have_ipv6
= 0;
614 const time_t now
= tr_time( );
616 /* Re-check every half hour */
617 if( last_time
< now
- 1800 )
620 const int rc
= tr_globalAddress( AF_INET6
, ipv6
, &addrlen
);
621 have_ipv6
= ( rc
>= 0 ) && ( addrlen
== 16 );
625 return have_ipv6
? ipv6
: NULL
;
634 isIPv4MappedAddress( const tr_address
* addr
)
636 return ( addr
->type
== TR_AF_INET6
) && IN6_IS_ADDR_V4MAPPED( &addr
->addr
.addr6
);
640 isIPv6LinkLocalAddress( const tr_address
* addr
)
642 return ( ( addr
->type
== TR_AF_INET6
)
643 && IN6_IS_ADDR_LINKLOCAL( &addr
->addr
.addr6
) );
646 /* isMartianAddr was written by Juliusz Chroboczek,
647 and is covered under the same license as third-party/dht/dht.c. */
649 isMartianAddr( const struct tr_address
* a
)
651 static const unsigned char zeroes
[16] =
652 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
654 assert( tr_isAddress( a
) );
659 const unsigned char * address
= (const unsigned char*)&a
->addr
.addr4
;
660 return (address
[0] == 0) ||
661 (address
[0] == 127) ||
662 ((address
[0] & 0xE0) == 0xE0);
667 const unsigned char * address
= (const unsigned char*)&a
->addr
.addr6
;
668 return (address
[0] == 0xFF) ||
669 (memcmp(address
, zeroes
, 15) == 0 &&
670 (address
[15] == 0 || address
[15] == 1)) ||
671 /* Addresses outside of 2000::/3 are currently reserved,
672 but might be allocated at some future time. Since
673 there are a lot of buggy peers pushing around such
674 addresses over PEX, we reject them until the end of
676 (tr_time() < 1356130800 && (address
[0] & 0xE0) != 0x20);
686 tr_isValidPeerAddress( const tr_address
* addr
, tr_port port
)
689 && ( tr_isAddress( addr
) )
690 && ( !isIPv6LinkLocalAddress( addr
) )
691 && ( !isIPv4MappedAddress( addr
) )
692 && ( !isMartianAddr( addr
) );