The following commit has been merged in the master branch: commit 933e84f3b52b3c789def0e7379b9a3dd320f679b Author: Marek Lindner lindner_marek@yahoo.de Date: Mon Oct 2 02:13:45 2006 +0200
udp tunnel part I
diff --git a/batman.c b/batman.c index 7fe6901..d82e8e5 100755 --- a/batman.c +++ b/batman.c @@ -69,12 +69,14 @@ int routing_class = 0; int orginator_interval = 1000; /* orginator message interval in miliseconds */
struct gw_node *curr_gateway = NULL; -struct batman_if *curr_gateway_batman_if = NULL; -unsigned int curr_gateway_ip = 0; -char *curr_gateway_ipip_if = NULL; pthread_t curr_gateway_thread_id = 0; + +/*struct batman_if *curr_gateway_batman_if = NULL; +unsigned int curr_gateway_ip = 0; +char *curr_gateway_tun_if = NULL; int curr_gateway_tcp_sock = 0; -int curr_gateway_ipip_fd = 0; +int curr_gateway_tun_sock = 0; +int curr_gateway_tun_fd = 0;*/
unsigned int pref_gateway = 0; int found_ifs = 0; @@ -265,8 +267,8 @@ static void choose_gw() output( "Adding default route to %s (%i,%i,%i)\n", orig_str, max_gw_class, max_packets, max_gw_factor ); }
- curr_gateway_ip = curr_gateway->orig_node->orig; - curr_gateway_batman_if = curr_gateway->orig_node->batman_if; + /*curr_gateway_ip = curr_gateway->orig_node->orig; + curr_gateway_batman_if = curr_gateway->orig_node->batman_if;*/
}
diff --git a/batman.h b/batman.h index 5122672..272ce00 100755 --- a/batman.h +++ b/batman.h @@ -50,12 +50,14 @@ extern int routing_class; extern unsigned int pref_gateway;
extern struct gw_node *curr_gateway; -extern struct batman_if *curr_gateway_batman_if; -extern unsigned int curr_gateway_ip; -extern char *curr_gateway_ipip_if; pthread_t curr_gateway_thread_id; + +/*extern struct batman_if *curr_gateway_batman_if; +extern unsigned int curr_gateway_ip; +extern char *curr_gateway_tun_if; extern int curr_gateway_tcp_sock; -extern int curr_gateway_ipip_fd; +extern int curr_gateway_tun_sock; +extern int curr_gateway_tun_fd;*/
extern int found_ifs;
@@ -124,6 +126,7 @@ struct batman_if int udp_send_sock; int udp_recv_sock; int tcp_gw_sock; + int tunnel_sock; int if_num; pthread_t listen_thread_id; struct sockaddr_in addr; @@ -138,8 +141,6 @@ struct gw_client struct batman_if *batman_if; int sock; unsigned int last_keep_alive; - char *tun_dev; - int tun_fd; struct sockaddr_in addr; };
diff --git a/bsd.c b/bsd.c index 18c1db0..e0ee8ac 100644 --- a/bsd.c +++ b/bsd.c @@ -199,13 +199,13 @@ void add_del_route(unsigned int dest, unsigned int router, int del, } }
-int del_ipip_tun(int fd) +int del_dev_tun(int fd) { /* Implement me! */ return 1; }
-int add_ipip_tun( struct batman_if *batman_if, unsigned int dest_addr, char *tun_dev, int *fd ) +int add_dev_tun( struct batman_if *batman_if, unsigned int dest_addr, char *tun_dev, int *fd ) { /* Implement me! */ return 0; diff --git a/linux.c b/linux.c index e5fa92e..59c32bf 100755 --- a/linux.c +++ b/linux.c @@ -143,11 +143,13 @@ int probe_tun()
}
+ close( fd ); + return 1;
}
-int del_ipip_tun( int fd ) { +int del_dev_tun( int fd ) {
if ( ioctl( fd, TUNSETPERSIST, 0 ) < 0 ) {
@@ -162,7 +164,7 @@ int del_ipip_tun( int fd ) {
}
-int add_ipip_tun( struct batman_if *batman_if, unsigned int dest_addr, char *tun_dev, int *fd ) { +int add_dev_tun( struct batman_if *batman_if, unsigned int dest_addr, char *tun_dev, int *fd ) {
int tmp_fd; struct ifreq ifr; @@ -200,7 +202,7 @@ int add_ipip_tun( struct batman_if *batman_if, unsigned int dest_addr, char *tun
if ( tmp_fd < 0 ) { fprintf(stderr, "Cannot create send socket: %s", strerror(errno)); - del_ipip_tun( *fd ); + del_dev_tun( *fd ); return -1; }
@@ -215,14 +217,15 @@ int add_ipip_tun( struct batman_if *batman_if, unsigned int dest_addr, char *tun if ( ioctl( tmp_fd, SIOCSIFADDR, &ifr) < 0 ) {
perror("SIOCSIFADDR"); - del_ipip_tun( *fd ); + del_dev_tun( *fd ); close( tmp_fd ); return -1;
}
+ /* TODO: remove dest_addr from function call */ /* set ip of this remote point of tunnel */ - memset( &addr, 0, sizeof(addr) ); + /*memset( &addr, 0, sizeof(addr) ); addr.sin_addr.s_addr = dest_addr; addr.sin_family = AF_INET; memcpy( &ifr.ifr_addr, &addr, sizeof(struct sockaddr) ); @@ -230,16 +233,16 @@ int add_ipip_tun( struct batman_if *batman_if, unsigned int dest_addr, char *tun if ( ioctl( tmp_fd, SIOCSIFDSTADDR, &ifr) < 0 ) {
perror("SIOCSIFDSTADDR"); - del_ipip_tun( *fd ); + del_dev_tun( *fd ); close( tmp_fd ); return -1;
- } + }*/
if ( ioctl( tmp_fd, SIOCGIFFLAGS, &ifr) < 0 ) {
perror("SIOCGIFFLAGS"); - del_ipip_tun( *fd ); + del_dev_tun( *fd ); close( tmp_fd ); return -1;
@@ -251,14 +254,14 @@ int add_ipip_tun( struct batman_if *batman_if, unsigned int dest_addr, char *tun if ( ioctl( tmp_fd, SIOCSIFFLAGS, &ifr) < 0 ) {
perror("SIOCSIFFLAGS"); - del_ipip_tun( *fd ); + del_dev_tun( *fd ); close( tmp_fd ); return -1;
}
close( tmp_fd ); - strncpy( tun_dev, ifr.ifr_name, IFNAMSIZ ); + strncpy( tun_dev, ifr.ifr_name, IFNAMSIZ - 1 );
return 1;
diff --git a/os.h b/os.h index dce6861..0197869 100755 --- a/os.h +++ b/os.h @@ -37,7 +37,7 @@ int send_packet(unsigned char *buff, int len, struct sockaddr_in *broad, int soc int rand_num(int limit); int bind_to_iface( int udp_recv_sock, char *dev ); int probe_tun(); -int del_ipip_tun( int fd ); -int add_ipip_tun( struct batman_if *batman_if, unsigned int dest_addr, char *tun_dev, int *fd ); +int del_dev_tun( int fd ); +int add_dev_tun( struct batman_if *batman_if, unsigned int dest_addr, char *tun_dev, int *fd );
#endif diff --git a/posix.c b/posix.c index f7d6ba4..0479466 100644 --- a/posix.c +++ b/posix.c @@ -86,15 +86,96 @@ void output(char *format, ...)
-void *keep_tun_alive( void *unused ) { +void *client_to_gw_tun( void *arg ) {
+ struct gw_node *gw_node = (struct gw_node *)arg; + struct batman_if *curr_gateway_batman_if; + struct sockaddr_in gw_addr, my_addr; struct timeval tv; - int res; + int res, max_sock, curr_gateway_tcp_sock, curr_gateway_tun_sock, curr_gateway_tun_fd; + unsigned int curr_gateway_ip; + char curr_gateway_tun_if[IFNAMSIZ], buff[1500]; fd_set wait_sockets, tmp_wait_sockets;
+ curr_gateway_ip = gw_node->orig_node->orig; + curr_gateway_batman_if = gw_node->orig_node->batman_if; + + memset( &gw_addr, 0, sizeof(struct sockaddr_in) ); + memset( &my_addr, 0, sizeof(struct sockaddr_in) ); + + gw_addr.sin_family = AF_INET; + gw_addr.sin_port = htons(PORT + 1); + gw_addr.sin_addr.s_addr = curr_gateway_ip; + + my_addr.sin_family = AF_INET; + my_addr.sin_port = htons(PORT + 1); + my_addr.sin_addr.s_addr = curr_gateway_batman_if->addr.sin_addr.s_addr; + + + /* connect to server (ask permission) */ + if ( ( curr_gateway_tcp_sock = socket(PF_INET, SOCK_STREAM, 0) ) < 0 ) { + + perror("socket"); + curr_gateway = NULL; + return NULL; + + } + + if ( connect ( curr_gateway_tcp_sock, (struct sockaddr *)&gw_addr, sizeof(struct sockaddr) ) < 0 ) { + + perror("connect"); + curr_gateway = NULL; + close( curr_gateway_tcp_sock ); + return NULL; + + } + + /* connect to server (establish udp tunnel) */ + if ( ( curr_gateway_tun_sock = socket(PF_INET, SOCK_DGRAM, 0) ) < 0 ) { + + perror("connect"); + curr_gateway = NULL; + close( curr_gateway_tcp_sock ); + return NULL; + + } + + if ( bind( curr_gateway_tun_sock, (struct sockaddr *)&my_addr, sizeof (struct sockaddr_in) ) < 0) { + fprintf(stderr, "Cannot bind tunnel socket: %s\n", strerror(errno)); + curr_gateway = NULL; + close( curr_gateway_tcp_sock ); + close( curr_gateway_tun_sock ); + return NULL; + } + + + + if ( add_dev_tun( curr_gateway_batman_if, curr_gateway_ip, curr_gateway_tun_if, &curr_gateway_tun_fd ) > 0 ) { + +// add_del_route( 0, curr_gateway_ip, 0, curr_gateway_tun_if, curr_gateway_tun_fd ); + + } else { + + fprintf(stderr, "Cannot create tunnel device: %s\n", strerror(errno)); + curr_gateway = NULL; + close( curr_gateway_tcp_sock ); + close( curr_gateway_tun_sock ); + return NULL; + + } + + FD_ZERO(&wait_sockets); FD_SET(curr_gateway_tcp_sock, &wait_sockets); + FD_SET(curr_gateway_tun_sock, &wait_sockets); + FD_SET(curr_gateway_tun_fd, &wait_sockets); + + max_sock = curr_gateway_tcp_sock; + if ( curr_gateway_tun_sock > max_sock ) + max_sock = curr_gateway_tun_sock; + if ( curr_gateway_tun_fd > max_sock ) + max_sock = curr_gateway_tun_fd;
while ( ( !is_aborted() ) && ( curr_gateway != NULL ) ) {
@@ -105,93 +186,74 @@ void *keep_tun_alive( void *unused ) {
res = select(curr_gateway_tcp_sock + 1, &wait_sockets, NULL, NULL, &tv);
- if (res > 0) { + if ( res > 0 ) {
- /* TODO: if server sends a message (e.g. rejects) */ + /* tcp message from server */ + if ( FD_ISSET( curr_gateway_tcp_sock, &tmp_wait_sockets ) ) {
- } else if ( ( res < 0 ) && (errno != EINTR) ) { + /* TODO: if server sends a message (e.g. rejects) */
- fprintf(stderr, "Cannot select: %s\n", strerror(errno)); - del_default_route(); - return NULL; + /* udp message (tunnel data) */ + } else if ( FD_ISSET( curr_gateway_tun_sock, &tmp_wait_sockets ) ) {
- }
+ } else if ( FD_ISSET( curr_gateway_tun_fd, &tmp_wait_sockets ) ) {
- } + if ( read( curr_gateway_tun_fd, buff, sizeof( buff ) ) < 0 ) {
- return NULL; + fprintf(stderr, "Could not read data from %s: %s\n", curr_gateway_tun_if, strerror(errno));
-} - -void del_default_route() { - - curr_gateway = NULL; - - add_del_route( 0, curr_gateway_ip, 1, curr_gateway_ipip_if, curr_gateway_ipip_fd ); - - close( curr_gateway_tcp_sock ); - del_ipip_tun( curr_gateway_ipip_fd ); + } else {
- curr_gateway_tcp_sock = 0; - curr_gateway_ipip_fd = 0; + if ( sendto(curr_gateway_tun_sock, buff, sizeof( buff ), 0, (struct sockaddr *)&gw_addr, sizeof (struct sockaddr_in) ) < 0 ) { + fprintf(stderr, "Cannot send to gateway: %s\n", strerror(errno)); + }
- if ( curr_gateway_thread_id != 0 ) - pthread_join( curr_gateway_thread_id, NULL ); + }
-} + }
+ } else if ( ( res < 0 ) && (errno != EINTR) ) {
+ fprintf(stderr, "Cannot select: %s\n", strerror(errno)); + del_default_route(); + return NULL;
-int add_default_route() { + }
- struct sockaddr_in gw_addr; /* connector's address information */
- memset( &gw_addr, 0, sizeof(struct sockaddr_in) ); - gw_addr.sin_family = AF_INET; - gw_addr.sin_port = htons(PORT); - gw_addr.sin_addr.s_addr = curr_gateway_ip;
- /* connect to server and keep alive */ - if ( ( curr_gateway_tcp_sock = socket(PF_INET, SOCK_STREAM, 0) ) < 0 ) { + }
- perror("socket"); - curr_gateway = NULL; - return -1; + /* cleanup */ +// add_del_route( 0, curr_gateway_ip, 1, curr_gateway_tun_if, curr_gateway_tun_fd );
- } + close( curr_gateway_tcp_sock ); + close( curr_gateway_tun_sock );
- if ( connect ( curr_gateway_tcp_sock, (struct sockaddr *)&gw_addr, sizeof(struct sockaddr) ) < 0 ) { + del_dev_tun( curr_gateway_tun_fd );
- perror("connect"); - curr_gateway = NULL; - close( curr_gateway_tcp_sock ); - return -1; + return NULL;
- } +}
- pthread_create( &curr_gateway_thread_id, NULL, &keep_tun_alive, NULL ); +void del_default_route() {
- if ( curr_gateway_ipip_if == NULL ) - curr_gateway_ipip_if = alloc_memory( sizeof(IFNAMSIZ) ); + curr_gateway = NULL;
- if ( add_ipip_tun( curr_gateway_batman_if, curr_gateway_ip, curr_gateway_ipip_if, &curr_gateway_ipip_fd ) > 0 ) { + if ( curr_gateway_thread_id != 0 ) + pthread_join( curr_gateway_thread_id, NULL );
- add_del_route( 0, curr_gateway_ip, 0, curr_gateway_ipip_if, curr_gateway_ipip_fd ); - return 1; +}
- } else {
- curr_gateway = NULL; - close( curr_gateway_tcp_sock );
- if ( curr_gateway_thread_id != 0 ) - pthread_join( curr_gateway_thread_id, NULL ); +int add_default_route() {
- return -1; + pthread_create( &curr_gateway_thread_id, NULL, &client_to_gw_tun, curr_gateway );
- } + return 1;
}
@@ -368,16 +430,35 @@ void *gw_listen( void *arg ) { struct gw_client *gw_client; struct list_head *client_pos, *client_pos_tmp; struct timeval tv; + struct sockaddr_in addr; socklen_t sin_size = sizeof(struct sockaddr_in); - char str1[16], str2[16]; - int res, max_sock; - unsigned int client_timeout = get_time(); + ssize_t recv_len; + char gw_addr[16], str2[16], tun_dev[IFNAMSIZ], buff[1500]; + int res, max_sock, tun_fd; + unsigned int addr_len, client_timeout; fd_set wait_sockets, tmp_wait_sockets;
+ addr_to_string(batman_if->addr.sin_addr.s_addr, gw_addr, sizeof (gw_addr)); + addr_len = sizeof (struct sockaddr_in); + client_timeout = get_time(); + + if ( add_dev_tun( batman_if, 0, tun_dev, &tun_fd ) < 0 ) { + printf( "Could not open tun device on interface: %s\n", gw_addr ); + return NULL; + } + + FD_ZERO(&wait_sockets); FD_SET(batman_if->tcp_gw_sock, &wait_sockets); + FD_SET(batman_if->tunnel_sock, &wait_sockets); + FD_SET(tun_fd, &wait_sockets); + max_sock = batman_if->tcp_gw_sock; + if ( batman_if->tunnel_sock > max_sock ) + max_sock = batman_if->tunnel_sock; + if ( tun_fd > max_sock ) + max_sock = tun_fd;
while (!is_aborted()) {
@@ -403,24 +484,39 @@ void *gw_listen( void *arg ) { INIT_LIST_HEAD(&gw_client->list); gw_client->batman_if = batman_if; gw_client->last_keep_alive = get_time(); - gw_client->tun_dev = alloc_memory( sizeof(IFNAMSIZ) );
- if ( add_ipip_tun( batman_if, gw_client->addr.sin_addr.s_addr, gw_client->tun_dev, &gw_client->tun_fd ) > 0 ) { + FD_SET(gw_client->sock, &wait_sockets); + if ( gw_client->sock > max_sock ) + max_sock = gw_client->sock;
- FD_SET(gw_client->sock, &wait_sockets); - if ( gw_client->sock > max_sock ) - max_sock = gw_client->sock; + list_add_tail(&gw_client->list, &batman_if->client_list);
- list_add_tail(&gw_client->list, &batman_if->client_list); + if ( debug_level >= 1 ) { + addr_to_string(gw_client->addr.sin_addr.s_addr, str2, sizeof (str2)); + printf( "gateway: %s (%s) got connection from %s (internet via %s)\n", gw_addr, batman_if->dev, str2, tun_dev ); + }
- if ( debug_level >= 1 ) { - addr_to_string(batman_if->addr.sin_addr.s_addr, str1, sizeof (str1)); - addr_to_string(gw_client->addr.sin_addr.s_addr, str2, sizeof (str2)); - printf( "gateway: %s (%s) got connection from %s (internet via %s)\n", str1, batman_if->dev, str2, gw_client->tun_dev ); - } + /* tunnel activity */ + } else if ( FD_ISSET( batman_if->tunnel_sock, &tmp_wait_sockets ) ) { + + if ( ( recv_len = recvfrom( batman_if->tunnel_sock, buff, sizeof( buff ), 0, (struct sockaddr *)&addr, &addr_len ) ) < 0 ) + { + fprintf(stderr, "Cannot receive packet: %s\n", strerror(errno)); + } + + buff[recv_len] = '\0'; + + if ( write( tun_fd, buff, sizeof( buff ) ) < 0 ) { + + fprintf(stderr, "Cannot write packet into %s: %s\n", tun_dev, strerror(errno));
}
+ /* /dev/tunX activity */ + } else if ( FD_ISSET( tun_fd, &tmp_wait_sockets ) ) { + + /* TODO: paste to client */ + /* client sent keep alive */ } else {
@@ -457,7 +553,12 @@ void *gw_listen( void *arg ) { if ( ( client_timeout + 59000 ) < get_time() ) {
client_timeout = get_time(); + max_sock = batman_if->tcp_gw_sock; + if ( batman_if->tunnel_sock > max_sock ) + max_sock = batman_if->tunnel_sock; + if ( tun_fd > max_sock ) + max_sock = tun_fd;
list_for_each_safe(client_pos, client_pos_tmp, &batman_if->client_list) {
@@ -467,7 +568,6 @@ void *gw_listen( void *arg ) {
FD_CLR(gw_client->sock, &wait_sockets); close( gw_client->sock ); - del_ipip_tun( gw_client->tun_fd );
if ( debug_level >= 1 ) { addr_to_string(gw_client->addr.sin_addr.s_addr, str2, sizeof (str2)); @@ -490,14 +590,8 @@ void *gw_listen( void *arg ) {
}
- /* delete all ipip devices on exit */ - list_for_each(client_pos, &batman_if->client_list) { - - gw_client = list_entry(client_pos, struct gw_client, list); - - del_ipip_tun( gw_client->tun_fd ); - - } + /* delete tun devices on exit */ + del_dev_tun( tun_fd );
return NULL;
@@ -510,7 +604,7 @@ int main(int argc, char *argv[]) struct in_addr tmp_ip_holder; struct batman_if *batman_if; struct ifreq int_req; - int on = 1, res, optchar, found_args = 1, fd; + int on = 1, res, optchar, found_args = 1; char str1[16], str2[16], *dev; unsigned int vis_server = 0;
@@ -662,6 +756,7 @@ int main(int argc, char *argv[]) batman_if->udp_send_sock = socket(PF_INET, SOCK_DGRAM, 0); if (batman_if->udp_send_sock < 0) { fprintf(stderr, "Cannot create send socket: %s", strerror(errno)); + close_all_sockets(); exit(EXIT_FAILURE); }
@@ -733,6 +828,8 @@ int main(int argc, char *argv[])
if ( gateway_class != 0 ) {
+ batman_if->addr.sin_port = htons(PORT + 1); + batman_if->tcp_gw_sock = socket(PF_INET, SOCK_STREAM, 0);
if (batman_if->tcp_gw_sock < 0) { @@ -759,6 +856,22 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); }
+ batman_if->tunnel_sock = socket(PF_INET, SOCK_DGRAM, 0); + if (batman_if->tunnel_sock < 0) { + fprintf(stderr, "Cannot create tunnel socket: %s", strerror(errno)); + close_all_sockets(); + exit(EXIT_FAILURE); + } + + if (bind(batman_if->tunnel_sock, (struct sockaddr *)&batman_if->addr, sizeof (struct sockaddr_in)) < 0) + { + fprintf(stderr, "Cannot bind tunnel socket: %s\n", strerror(errno)); + close_all_sockets(); + exit(EXIT_FAILURE); + } + + batman_if->addr.sin_port = htons(PORT); + pthread_create(&batman_if->listen_thread_id, NULL, &gw_listen, batman_if);
} @@ -816,13 +929,19 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); }
- close( fd );
+ if ( debug_level > 0 ) + printf("debug level: %i\n", debug_level); + + if ( ( debug_level > 0 ) && ( orginator_interval != 1000 ) ) + printf( "orginator interval: %i\n", orginator_interval ); + + if ( ( debug_level > 0 ) && ( gateway_class > 0 ) ) + printf( "gateway class: %i\n", gateway_class ); + + if ( ( debug_level > 0 ) && ( routing_class > 0 ) ) + printf( "routing class: %i\n", routing_class );
- if ( debug_level > 0 ) printf("debug level: %i\n", debug_level); - if ( ( debug_level > 0 ) && ( orginator_interval != 1000 ) ) printf( "orginator interval: %i\n", orginator_interval ); - if ( ( debug_level > 0 ) && ( gateway_class > 0 ) ) printf( "gateway class: %i\n", gateway_class ); - if ( ( debug_level > 0 ) && ( routing_class > 0 ) ) printf( "routing class: %i\n", routing_class ); if ( ( debug_level > 0 ) && ( pref_gateway > 0 ) ) { addr_to_string(pref_gateway, str1, sizeof (str1)); printf( "preferred gateway: %s\n", str1 );