Move handling of UDP I/O to tr-udp.c.
This commit is contained in:
parent
0d8c10716c
commit
aa3868df06
|
@ -130,6 +130,8 @@ struct tr_session
|
||||||
int udp_socket;
|
int udp_socket;
|
||||||
int udp6_socket;
|
int udp6_socket;
|
||||||
unsigned char * udp6_bound;
|
unsigned char * udp6_bound;
|
||||||
|
struct event *udp_event;
|
||||||
|
struct event *udp6_event;
|
||||||
|
|
||||||
/* The open port on the local machine for incoming peer requests */
|
/* The open port on the local machine for incoming peer requests */
|
||||||
tr_port private_peer_port;
|
tr_port private_peer_port;
|
||||||
|
|
|
@ -59,11 +59,11 @@ THE SOFTWARE.
|
||||||
#include "trevent.h" /* tr_runInEventThread() */
|
#include "trevent.h" /* tr_runInEventThread() */
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
static struct event dht_event, dht6_event;
|
static struct event dht_timer;
|
||||||
static unsigned char myid[20];
|
static unsigned char myid[20];
|
||||||
static tr_session *session = NULL;
|
static tr_session *session = NULL;
|
||||||
|
|
||||||
static void event_callback(int s, short type, void *ignore);
|
static void timer_callback(int s, short type, void *ignore);
|
||||||
|
|
||||||
struct bootstrap_closure {
|
struct bootstrap_closure {
|
||||||
tr_session *session;
|
tr_session *session;
|
||||||
|
@ -315,14 +315,8 @@ tr_dhtInit(tr_session *ss)
|
||||||
cl->len6 = len6;
|
cl->len6 = len6;
|
||||||
tr_threadNew( dht_bootstrap, cl );
|
tr_threadNew( dht_bootstrap, cl );
|
||||||
|
|
||||||
event_set( &dht_event, ss->udp_socket, EV_READ, event_callback, NULL );
|
evtimer_set( &dht_timer, timer_callback, session );
|
||||||
tr_timerAdd( &dht_event, 0, tr_cryptoWeakRandInt( 1000000 ) );
|
tr_timerAdd( &dht_timer, 0, tr_cryptoWeakRandInt( 1000000 ) );
|
||||||
|
|
||||||
if( ss->udp6_socket >= 0 )
|
|
||||||
{
|
|
||||||
event_set( &dht6_event, ss->udp6_socket, EV_READ, event_callback, NULL );
|
|
||||||
tr_timerAdd( &dht6_event, 0, tr_cryptoWeakRandInt( 1000000 ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
tr_ndbg( "DHT", "DHT initialized" );
|
tr_ndbg( "DHT", "DHT initialized" );
|
||||||
|
|
||||||
|
@ -342,11 +336,7 @@ tr_dhtUninit(tr_session *ss)
|
||||||
|
|
||||||
tr_ndbg( "DHT", "Uninitializing DHT" );
|
tr_ndbg( "DHT", "Uninitializing DHT" );
|
||||||
|
|
||||||
event_free( dht_event );
|
event_del( &dht_timer );
|
||||||
dht_event = NULL;
|
|
||||||
|
|
||||||
if( ss->udp6_socket >= 0 )
|
|
||||||
event_del( &dht6_event );
|
|
||||||
|
|
||||||
/* Since we only save known good nodes, avoid erasing older data if we
|
/* Since we only save known good nodes, avoid erasing older data if we
|
||||||
don't know enough nodes. */
|
don't know enough nodes. */
|
||||||
|
@ -590,43 +580,25 @@ tr_dhtAnnounce(tr_torrent *tor, int af, tr_bool announce)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
event_callback(int s, short type, void *ignore UNUSED )
|
tr_dhtCallback(unsigned char *buf, int buflen,
|
||||||
|
struct sockaddr *from, socklen_t fromlen,
|
||||||
|
void *sv )
|
||||||
{
|
{
|
||||||
struct event *event;
|
tr_session *ss = (tr_session*)sv;
|
||||||
time_t tosleep;
|
time_t tosleep;
|
||||||
struct sockaddr_storage from;
|
|
||||||
socklen_t fromlen;
|
|
||||||
unsigned char *buf = NULL;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (s == session->udp_socket)
|
assert(tr_isSession(ss));
|
||||||
event = &dht_event;
|
|
||||||
else if(s == session->udp6_socket)
|
if(sv != session) {
|
||||||
event = &dht6_event;
|
tr_nerr("DHT", "tr_dhtCallback called for unexpected session");
|
||||||
else {
|
return;
|
||||||
tr_nerr("DHT", "Event on unexpected socket");
|
|
||||||
event = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( type == EV_READ ) {
|
rc = dht_periodic( buf, buflen, from, fromlen,
|
||||||
buf = malloc(4096);
|
&tosleep, callback, NULL);
|
||||||
if(buf != NULL) {
|
if(rc < 0) {
|
||||||
fromlen = sizeof(from);
|
|
||||||
rc = recvfrom(s, buf, 4096 - 1, 0,
|
|
||||||
(struct sockaddr*)&from, &fromlen);
|
|
||||||
if(rc < 0)
|
|
||||||
rc = 0;
|
|
||||||
else
|
|
||||||
buf[rc] = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rc = 0;
|
|
||||||
fromlen = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( dht_periodic( buf, rc, (struct sockaddr*)&from, fromlen,
|
|
||||||
&tosleep, callback, NULL) < 0 ) {
|
|
||||||
if(errno == EINTR) {
|
if(errno == EINTR) {
|
||||||
tosleep = 0;
|
tosleep = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -637,28 +609,18 @@ event_callback(int s, short type, void *ignore UNUSED )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(buf) {
|
|
||||||
free(buf);
|
|
||||||
buf = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef NOTYET
|
|
||||||
/* Only do this once in a while. Counting rather than measuring time
|
|
||||||
avoids a system call. */
|
|
||||||
count++;
|
|
||||||
if(count >= 20) {
|
|
||||||
rebind_ipv6(FALSE);
|
|
||||||
count = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(event) {
|
|
||||||
/* Being slightly late is fine,
|
/* Being slightly late is fine,
|
||||||
and has the added benefit of adding some jitter. */
|
and has the added benefit of adding some jitter. */
|
||||||
tr_timerAdd( event, tosleep, tr_cryptoWeakRandInt( 1000000 ) );
|
tr_timerAdd( &dht_timer, tosleep, tr_cryptoWeakRandInt( 1000000 ) );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
timer_callback(int s UNUSED, short type UNUSED, void *session )
|
||||||
|
{
|
||||||
|
tr_dhtCallback(NULL, 0, NULL, 0, session);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
dht_hash(void *hash_return, int hash_size,
|
dht_hash(void *hash_return, int hash_size,
|
||||||
const void *v1, int len1,
|
const void *v1, int len1,
|
||||||
|
|
|
@ -44,3 +44,6 @@ int tr_dhtStatus( tr_session *, int af, int * setme_nodeCount );
|
||||||
const char *tr_dhtPrintableStatus(int status);
|
const char *tr_dhtPrintableStatus(int status);
|
||||||
int tr_dhtAddNode( tr_session *, const tr_address *, tr_port, tr_bool bootstrap );
|
int tr_dhtAddNode( tr_session *, const tr_address *, tr_port, tr_bool bootstrap );
|
||||||
int tr_dhtAnnounce( tr_torrent *, int af, tr_bool announce );
|
int tr_dhtAnnounce( tr_torrent *, int af, tr_bool announce );
|
||||||
|
void tr_dhtCallback(unsigned char *buf, int buflen,
|
||||||
|
struct sockaddr *from, socklen_t fromlen,
|
||||||
|
void *sv);
|
||||||
|
|
|
@ -24,6 +24,8 @@ THE SOFTWARE.
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <event.h>
|
||||||
|
|
||||||
#include "transmission.h"
|
#include "transmission.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "session.h"
|
#include "session.h"
|
||||||
|
@ -103,6 +105,42 @@ rebind_ipv6(tr_session *ss, tr_bool force)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
event_callback(int s, short type, void *sv)
|
||||||
|
{
|
||||||
|
tr_session *ss = (tr_session*)sv;
|
||||||
|
unsigned char *buf;
|
||||||
|
struct sockaddr_storage from;
|
||||||
|
socklen_t fromlen;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
assert(tr_isSession(ss));
|
||||||
|
assert(type == EV_READ);
|
||||||
|
|
||||||
|
buf = malloc(4096);
|
||||||
|
if(buf == NULL) {
|
||||||
|
tr_nerr("UDP", "Couldn't allocate buffer");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fromlen = sizeof(from);
|
||||||
|
rc = recvfrom(s, buf, 4096 - 1, 0,
|
||||||
|
(struct sockaddr*)&from, &fromlen);
|
||||||
|
if(rc <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(buf[0] == 'd') {
|
||||||
|
/* DHT packet. */
|
||||||
|
buf[rc] = '\0';
|
||||||
|
tr_dhtCallback(buf, rc, (struct sockaddr*)&from, fromlen, sv);
|
||||||
|
} else {
|
||||||
|
/* Probably a UTP packet. */
|
||||||
|
/* Nothing yet. */
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tr_udpInit(tr_session *ss, const tr_address * addr)
|
tr_udpInit(tr_session *ss, const tr_address * addr)
|
||||||
{
|
{
|
||||||
|
@ -122,6 +160,14 @@ tr_udpInit(tr_session *ss, const tr_address * addr)
|
||||||
goto ipv6;
|
goto ipv6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ss->udp_event = tr_new0(struct event, 1);
|
||||||
|
if(ss->udp_event == NULL) {
|
||||||
|
tr_nerr("UDP", "Couldn't allocate IPv4 event");
|
||||||
|
close(ss->udp_socket);
|
||||||
|
ss->udp_socket = -1;
|
||||||
|
goto ipv6;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&sin, 0, sizeof(sin));
|
memset(&sin, 0, sizeof(sin));
|
||||||
sin.sin_family = AF_INET;
|
sin.sin_family = AF_INET;
|
||||||
memcpy(&sin.sin_addr, &addr->addr.addr4, sizeof (struct in_addr));
|
memcpy(&sin.sin_addr, &addr->addr.addr4, sizeof (struct in_addr));
|
||||||
|
@ -134,12 +180,28 @@ tr_udpInit(tr_session *ss, const tr_address * addr)
|
||||||
goto ipv6;
|
goto ipv6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event_set(ss->udp_event, ss->udp_socket, EV_READ | EV_PERSIST,
|
||||||
|
event_callback, ss);
|
||||||
|
|
||||||
ipv6:
|
ipv6:
|
||||||
|
ss->udp6_event = tr_new0(struct event, 1);
|
||||||
|
if(ss->udp6_event == NULL) {
|
||||||
|
tr_nerr("UDP", "Couldn't allocate IPv6 event");
|
||||||
|
} else {
|
||||||
if(tr_globalIPv6())
|
if(tr_globalIPv6())
|
||||||
rebind_ipv6(ss, TRUE);
|
rebind_ipv6(ss, TRUE);
|
||||||
|
if(ss->udp6_socket >= 0)
|
||||||
|
event_set(ss->udp6_event, ss->udp6_socket, EV_READ | EV_PERSIST,
|
||||||
|
event_callback, ss);
|
||||||
|
}
|
||||||
|
|
||||||
if(ss->isDHTEnabled)
|
if(ss->isDHTEnabled)
|
||||||
tr_dhtInit(ss);
|
tr_dhtInit(ss);
|
||||||
|
|
||||||
|
if(ss->udp_event)
|
||||||
|
event_add(ss->udp_event, NULL);
|
||||||
|
if(ss->udp6_event)
|
||||||
|
event_add(ss->udp6_event, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -152,11 +214,23 @@ tr_udpUninit(tr_session *ss)
|
||||||
ss->udp_socket = -1;
|
ss->udp_socket = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(ss->udp_event) {
|
||||||
|
event_del(ss->udp_event);
|
||||||
|
free(ss->udp_event);
|
||||||
|
ss->udp_event = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if(ss->udp6_socket >= 0) {
|
if(ss->udp6_socket >= 0) {
|
||||||
tr_netCloseSocket( ss->udp6_socket );
|
tr_netCloseSocket( ss->udp6_socket );
|
||||||
ss->udp6_socket = -1;
|
ss->udp6_socket = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(ss->udp6_event) {
|
||||||
|
event_del(ss->udp6_event);
|
||||||
|
free(ss->udp6_event);
|
||||||
|
ss->udp6_event = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if(ss->udp6_bound) {
|
if(ss->udp6_bound) {
|
||||||
free(ss->udp6_bound);
|
free(ss->udp6_bound);
|
||||||
ss->udp6_bound = NULL;
|
ss->udp6_bound = NULL;
|
||||||
|
|
Loading…
Reference in New Issue