Browse Source

Network connection code seems to be working now

master
Dirk Engling 12 years ago
parent
commit
c6d5071afe
  1. 94
      proxy.c

94
proxy.c

@ -1,7 +1,7 @@
/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
It is considered beerware. Prost. Skol. Cheers or whatever.
$Id: proxy.c,v 1.4 2009/10/01 17:16:15 erdgeist Exp $ */
$Id: proxy.c,v 1.5 2009/10/02 23:34:42 erdgeist Exp $ */
/* System */
#include <stdint.h>
@ -211,7 +211,7 @@ static void livesync_handle_peersync( ssize_t datalen ) {
}
int usage( char *self ) {
fprintf( stderr, "Usage: %s -i ip -p port\n", self );
fprintf( stderr, "Usage: %s -L <livesync_iface_ip> -l <listenip>:<listenport> -c <connectip>:<connectport>\n", self );
return 0;
}
@ -274,6 +274,7 @@ static void handle_reconnects( void ) {
for( i=0; i<g_connection_count; ++i )
if( PROXYPEER_NEEDSCONNECT( g_connections[i].state ) ) {
int64 newfd = socket_tcp6( );
fprintf( stderr, "(Re)connecting to peer..." );
if( newfd < 0 ) continue; /* No socket for you */
io_fd(newfd);
if( socket_bind6_reuse(newfd,g_serverip,g_serverport,0) ) {
@ -389,6 +390,7 @@ close_socket:
indata_length should be less than 20+256*7 bytes, for incomplete torrent entries */
datalen = io_tryread( peersocket, (void*)(peer->indata + peer->indata_length), sizeof( peer->indata ) - peer->indata_length );
if( !datalen || datalen < -1 ) {
fprintf( stderr, "Connection closed by remote peer.\n" );
io_close( peersocket );
reset_info_block( peer );
} else if( datalen > 0 ) {
@ -402,6 +404,7 @@ close_socket:
/* Can write new sync data to the stream */
static void handle_write( int64 peersocket ) {
proxy_peer *peer = io_getcookie( peersocket );
if( !peer ) {
/* Can't happen ;) */
io_close( peersocket );
@ -416,25 +419,32 @@ static void handle_write( int64 peersocket ) {
case FLAG_CONNECTING:
/* Ensure that the connection is established and handle connection error */
if( peer->state & FLAG_OUTGOING && !socket_connected( peersocket ) ) {
fprintf( stderr, "failed\n" );
reset_info_block( peer );
io_close( peersocket );
break;
}
io_trywrite( peersocket, (void*)&g_tracker_id, sizeof( g_tracker_id ) );
PROXYPEER_SETWAITTRACKERID( peer->state );
fprintf( stderr, " succeeded.\n" );
io_dontwantwrite( peersocket );
io_wantread( peersocket );
break;
case FLAG_CONNECTED:
switch( iob_send( peersocket, &peer->outdata ) ) {
case 0: /* all data sent */
fprintf( stderr, "EMPTY\n" );
io_dontwantwrite( peersocket );
break;
case -3: /* an error occured */
fprintf( stderr, "ERROR\n" );
io_close( peersocket );
reset_info_block( peer );
break;
default: /* Normal operation or eagain */
fprintf( stderr, "EGAIN\n" );
break;
}
break;
@ -445,7 +455,6 @@ static void handle_write( int64 peersocket ) {
static void server_mainloop() {
int64 sock;
tai6464 now;
/* inlined livesync_init() */
memset( g_peerbuffer_start, 0, sizeof( g_peerbuffer_start ) );
@ -461,9 +470,7 @@ static void server_mainloop() {
handle_reconnects( );
/* Wait for io events until next approx reconn check time */
taia_now( &now );
taia_addsec( &now, &now, 30 );
io_waituntil( now );
io_waituntil2( 30*1000 );
/* Loop over readable sockets */
while( ( sock = io_canread( ) ) != -1 ) {
@ -482,31 +489,90 @@ static void server_mainloop() {
}
}
static void panic( const char *routine ) {
fprintf( stderr, "%s: %s\n", routine, strerror(errno) );
exit( 111 );
}
static int64_t ot_try_bind( ot_ip6 ip, uint16_t port ) {
int64 sock = socket_tcp6( );
if( socket_bind6_reuse( sock, ip, port, 0 ) == -1 )
panic( "socket_bind6_reuse" );
if( socket_listen( sock, SOMAXCONN) == -1 )
panic( "socket_listen" );
if( !io_fd( sock ) )
panic( "io_fd" );
io_setcookie( sock, (void*)FLAG_SERVERSOCKET );
io_wantread( sock );
return sock;
}
static int scan_ip6_port( const char *src, ot_ip6 ip, uint16 *port ) {
const char *s = src;
int off, bracket = 0;
while( isspace(*s) ) ++s;
if( *s == '[' ) ++s, ++bracket; /* for v6 style notation */
if( !(off = scan_ip6( s, ip ) ) )
return 0;
s += off;
if( *s == 0 || isspace(*s)) return s-src;
if( *s == ']' && bracket ) ++s;
if( !ip6_isv4mapped(ip)){
if( ( bracket && *(s) != ':' ) || ( *(s) != '.' ) ) return 0;
s++;
} else {
if( *(s++) != ':' ) return 0;
}
if( !(off = scan_ushort (s, port ) ) )
return 0;
return off+s-src;
}
int main( int argc, char **argv ) {
static pthread_t sync_in_thread_id;
static pthread_t sync_out_thread_id;
ot_ip6 serverip;
uint16_t tmpport;
int scanon = 1, bound = 0;
int scanon = 1, lbound = 0, sbound = 0;
srandom( time(NULL) );
g_tracker_id = random();
noipv6=1;
while( scanon ) {
switch( getopt( argc, argv, ":i:p:vh" ) ) {
switch( getopt( argc, argv, ":l:c:L:h" ) ) {
case -1: scanon = 0; break;
case 'S':
if( !scan_ip6( optarg, serverip )) { usage( argv[0] ); exit( 1 ); }
case 'l':
tmpport = 0;
if( !scan_ip6_port( optarg, serverip, &tmpport ) || !tmpport ) { usage( argv[0] ); exit( 1 ); }
ot_try_bind( serverip, tmpport );
++sbound;
break;
case 'c':
if( g_connection_count > MAX_PEERS / 2 ) exerr( "Connection limit exceeded.\n" );
tmpport = 0;
if( !scan_ip6_port( optarg,
g_connections[g_connection_count].ip,
&g_connections[g_connection_count].port ) ||
!g_connections[g_connection_count].port ) { usage( argv[0] ); exit( 1 ); }
g_connections[g_connection_count++].state = FLAG_OUTGOING;
break;
case 'p':
if( !scan_ushort( optarg, &tmpport)) { usage( argv[0] ); exit( 1 ); }
livesync_bind_mcast( serverip, tmpport); bound++; break;
case 'L':
tmpport = 9696;
if( !scan_ip6_port( optarg, serverip, &tmpport ) || !tmpport ) { usage( argv[0] ); exit( 1 ); }
livesync_bind_mcast( serverip, tmpport); ++lbound; break;
default:
case '?': usage( argv[0] ); exit( 1 );
}
}
if( !bound ) exerr( "No port bound." );
if( !lbound ) exerr( "No livesync port bound." );
if( !g_connection_count && !sbound ) exerr( "No streamsync port bound." );
pthread_create( &sync_in_thread_id, NULL, livesync_worker, NULL );
pthread_create( &sync_out_thread_id, NULL, streamsync_worker, NULL );

Loading…
Cancel
Save