The following commit has been merged in the master branch:
commit 933e84f3b52b3c789def0e7379b9a3dd320f679b
Author: Marek Lindner <lindner_marek(a)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 );
--
batman; test conversation