From 447a43d63960802a7a29201c512246be11eb9c94 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Sun, 7 Jan 2001 20:19:35 +0000 Subject: [PATCH] - Added indirectdata and tcponly functionality. --- src/connection.h | 9 +++-- src/net.c | 49 +++++++++++++++++--------- src/net.h | 3 +- src/protocol.c | 92 +++++++++++++++++++++++++++++++++++++++++++----- src/protocol.h | 5 +-- 5 files changed, 125 insertions(+), 33 deletions(-) diff --git a/src/connection.h b/src/connection.h index 06e08ef1..eef63382 100644 --- a/src/connection.h +++ b/src/connection.h @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id: connection.h,v 1.1.2.6 2001/01/07 17:08:57 guus Exp $ + $Id: connection.h,v 1.1.2.7 2001/01/07 20:19:29 guus Exp $ */ #ifndef __TINC_CONNECTION_H__ @@ -59,9 +59,8 @@ typedef struct status_bits_t { int unused:18; } status_bits_t; -typedef struct option_bits_t { - int unused:32; -} option_bits_t; +#define OPTION_INDIRECT 0x0001 +#define OPTION_TCPONLY 0x0002 typedef struct connection_t { char *name; /* name of this connection */ @@ -69,7 +68,7 @@ typedef struct connection_t { char *hostname; /* the hostname of its real ip */ int protocol_version; /* used protocol */ short unsigned int port; /* port number for UDP traffic */ - long unsigned int options; /* options turned on for this connection */ + long int options; /* options turned on for this connection */ int flags; /* his flags */ int socket; /* our udp vpn socket */ diff --git a/src/net.c b/src/net.c index 54e91391..18e5951b 100644 --- a/src/net.c +++ b/src/net.c @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id: net.c,v 1.35.4.91 2001/01/07 17:08:58 guus Exp $ + $Id: net.c,v 1.35.4.92 2001/01/07 20:19:29 guus Exp $ */ #include "config.h" @@ -112,7 +112,7 @@ int xsend(connection_t *cl, vpn_packet_t *inpkt) cp outpkt.len = inpkt->len; - /* Encrypt the packet */ + /* Encrypt the packet. FIXME: we should use CBC, not CFB. */ EVP_EncryptInit(&ctx, cl->cipher_pkttype, cl->cipher_pktkey, cl->cipher_pktkey + cl->cipher_pkttype->key_len); EVP_EncryptUpdate(&ctx, outpkt.data, &outlen, inpkt->data, inpkt->len); @@ -163,28 +163,33 @@ cp outlen = outpkt.len+2; memcpy(&outpkt, inpkt, outlen); */ - +cp + return receive_packet(cl, &outpkt); +} + +int receive_packet(connection_t *cl, vpn_packet_t *packet) +{ if(debug_lvl >= DEBUG_TRAFFIC) syslog(LOG_ERR, _("Writing packet of %d bytes to tap device"), - outpkt.len); + packet->len); /* Fix mac address */ - memcpy(outpkt.data, mymac.net.mac.address.x, 6); + memcpy(packet->data, mymac.net.mac.address.x, 6); if(taptype == TAP_TYPE_TUNTAP) { - if(write(tap_fd, outpkt.data, outpkt.len) < 0) + if(write(tap_fd, packet->data, packet->len) < 0) syslog(LOG_ERR, _("Can't write to tun/tap device: %m")); else - total_tap_out += outpkt.len; + total_tap_out += packet->len; } else /* ethertap */ { - if(write(tap_fd, outpkt.data - 2, outpkt.len + 2) < 0) + if(write(tap_fd, packet->data - 2, packet->len + 2) < 0) syslog(LOG_ERR, _("Can't write to ethertap device: %m")); else - total_tap_out += outpkt.len + 2; + total_tap_out += packet->len + 2; } cp return 0; @@ -231,10 +236,6 @@ cp return 0; } - /* If we ourselves have indirectdata flag set, we should send only to our uplink! */ - - /* FIXME - check for indirection and reprogram it The Right Way(tm) this time. */ - if(!cl->status.validkey) { if(debug_lvl >= DEBUG_TRAFFIC) @@ -248,9 +249,12 @@ cp return 0; } - /* can we send it? can we? can we? huh? */ + /* Check if it has to go via UDP or TCP... */ cp - return xsend(cl, packet); + if(cl->options & OPTION_TCPONLY) + return send_tcppacket(cl, packet); + else + return xsend(cl, packet); } void flush_queue(connection_t *cl) @@ -698,7 +702,7 @@ int setup_myself(void) cp myself = new_connection(); - asprintf(&myself->hostname, "MYSELF"); /* FIXME? Do hostlookup on ourselves? */ + asprintf(&myself->hostname, "MYSELF"); myself->flags = 0; myself->protocol_version = PROT_CURRENT; @@ -797,6 +801,19 @@ cp keyexpires = time(NULL) + keylifetime; cp + /* Check some options */ + + if((cfg = get_config_val(config, config_indirectdata))) + { + if(cfg->data.val == stupid_true) + myself->options |= OPTION_INDIRECT; + } + + if((cfg = get_config_val(config, config_tcponly))) + { + if(cfg->data.val == stupid_true) + myself->options |= OPTION_TCPONLY; + } /* Activate ourselves */ myself->status.active = 1; diff --git a/src/net.h b/src/net.h index ddbd84df..f3357248 100644 --- a/src/net.h +++ b/src/net.h @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id: net.h,v 1.9.4.26 2001/01/07 17:09:01 guus Exp $ + $Id: net.h,v 1.9.4.27 2001/01/07 20:19:31 guus Exp $ */ #ifndef __TINC_NET_H__ @@ -113,6 +113,7 @@ extern char *status_text[10]; extern int str2opt(const char *); extern char *opt2str(int); extern int send_packet(ip_t, vpn_packet_t *); +extern int receive_packet(connection_t *, vpn_packet_t *); extern int setup_network_connections(void); extern void close_network_connections(void); extern void main_loop(void); diff --git a/src/protocol.c b/src/protocol.c index 46c4c7b8..0b3563ef 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id: protocol.c,v 1.28.4.74 2001/01/07 17:09:02 guus Exp $ + $Id: protocol.c,v 1.28.4.75 2001/01/07 20:19:31 guus Exp $ */ #include "config.h" @@ -587,6 +587,7 @@ cp int ack_h(connection_t *cl) { + config_t const *cfg; connection_t *old, *p; subnet_t *subnet; avl_node_t *node, *node2; @@ -621,6 +622,20 @@ cp if(!cl->status.outgoing) send_ack(cl); + /* Check some options */ + + if((cfg = get_config_val(cl->config, config_indirectdata))) + { + if(cfg->data.val == stupid_true) + cl->options |= OPTION_INDIRECT; + } + + if((cfg = get_config_val(cl->config, config_tcponly))) + { + if(cfg->data.val == stupid_true) + cl->options |= OPTION_TCPONLY; + } + /* Send him our subnets */ for(node = myself->subnet_tree->head; node; node = node->next) @@ -662,9 +677,15 @@ int send_add_subnet(connection_t *cl, subnet_t *subnet) { int x; char *netstr; + char *owner; cp + if(cl->options & OPTION_INDIRECT) + owner = myself->name; + else + owner = subnet->owner->name; + x = send_request(cl, "%d %s %s", ADD_SUBNET, - subnet->owner->name, netstr = net2str(subnet)); + owner, netstr = net2str(subnet)); free(netstr); cp return x; @@ -739,9 +760,14 @@ int send_del_subnet(connection_t *cl, subnet_t *subnet) { int x; char *netstr; + char *owner; cp - netstr = net2str(subnet); - x = send_request(cl, "%d %s %s", DEL_SUBNET, subnet->owner->name, netstr); + if(cl->options & OPTION_INDIRECT) + owner = myself->name; + else + owner = subnet->owner->name; + + x = send_request(cl, "%d %s %s", DEL_SUBNET, owner, netstr = net2str(subnet)); free(netstr); cp return x; @@ -819,7 +845,8 @@ cp int send_add_host(connection_t *cl, connection_t *other) { cp - return send_request(cl, "%d %s %lx:%d %lx", ADD_HOST, + if(!(cl->options & OPTION_INDIRECT)) + return send_request(cl, "%d %s %lx:%d %lx", ADD_HOST, other->name, other->address, other->port, other->options); } @@ -910,7 +937,8 @@ cp int send_del_host(connection_t *cl, connection_t *other) { cp - return send_request(cl, "%d %s %lx:%d %lx", DEL_HOST, + if(!(cl->options & OPTION_INDIRECT)) + return send_request(cl, "%d %s %lx:%d %lx", DEL_HOST, other->name, other->address, other->port, other->options); } @@ -1060,8 +1088,6 @@ cp return 0; } -/* Keepalive routines - FIXME: needs a closer look */ - int send_ping(connection_t *cl) { cp @@ -1102,7 +1128,8 @@ cp { p = (connection_t *)node->data; if(p != cl && p->status.meta && p->status.active) - send_request(p, "%d %s", KEY_CHANGED, from->name); + if(!(cl->options & OPTION_INDIRECT) || from == myself) + send_request(p, "%d %s", KEY_CHANGED, from->name); } cp return 0; @@ -1265,6 +1292,51 @@ cp return 0; } +int send_tcppacket(connection_t *cl, vpn_packet_t *packet) +{ + int x; + + x = send_request(cl->nexthop, "%d %hd", PACKET, packet->len); + + if(x) + return x; + + return send_meta(cl->nexthop, packet->data, packet->len); +} + +int tcppacket_h(connection_t *cl) +{ + vpn_packet_t packet; + char *p; + int todo, x; + + if(sscanf(cl->buffer, "%*d %hd", packet.len) != 1) + { + syslog(LOG_ERR, _("Got bad PACKET from %s (%s)"), cl->name, cl->hostname); + return -1; + } + + /* Evil hack. */ + + p = packet.data; + todo = packet.len; + + while(todo) + { + x = read(cl->meta_socket, p, todo); + if(x<0) + { + syslog(LOG_ERR, _("Error during reception of PACKET from %s (%s): %m"), cl->name, cl->hostname); + return -1; + } + + todo -= x; + p += x; + } + + return receive_packet(cl, &packet); +} + /* Jumptable for the request handlers */ int (*request_handlers[])(connection_t*) = { @@ -1274,6 +1346,7 @@ int (*request_handlers[])(connection_t*) = { add_host_h, del_host_h, add_subnet_h, del_subnet_h, key_changed_h, req_key_h, ans_key_h, + tcppacket_h, }; /* Request names */ @@ -1285,6 +1358,7 @@ char (*request_name[]) = { "ADD_HOST", "DEL_HOST", "ADD_SUBNET", "DEL_SUBNET", "KEY_CHANGED", "REQ_KEY", "ANS_KEY", + "PACKET", }; /* Status strings */ diff --git a/src/protocol.h b/src/protocol.h index 437f1e29..16248c03 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id: protocol.h,v 1.5.4.18 2001/01/07 17:09:06 guus Exp $ + $Id: protocol.h,v 1.5.4.19 2001/01/07 20:19:35 guus Exp $ */ #ifndef __TINC_PROTOCOL_H__ @@ -42,6 +42,7 @@ enum { ADD_HOST, DEL_HOST, ADD_SUBNET, DEL_SUBNET, KEY_CHANGED, REQ_KEY, ANS_KEY, + PACKET, LAST /* Guardian for the highest request number */ }; @@ -69,10 +70,10 @@ extern int send_del_subnet(connection_t*, subnet_t*); extern int send_key_changed(connection_t*, connection_t*); extern int send_req_key(connection_t*, connection_t*); extern int send_ans_key(connection_t*, connection_t*, char*); +extern int send_tcppacket(connection_t *, vpn_packet_t *); /* Old functions */ -extern int send_tcppacket(connection_t *, void *, int); extern int notify_others(connection_t *, connection_t *, int (*function)(connection_t*, connection_t*)); extern int receive_request(connection_t *); extern int check_id(char *); -- 2.20.1