X-Git-Url: https://tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Fprotocol.c;h=31d22064541658082f986741097036a056640744;hp=85a4047c2c9360886a96233504588b30209987ae;hb=54881faf6fdbf04fb5ee56b7809439fbc50c65cb;hpb=e924096f62655d711cd2d114a8d1ef0fecbb593b diff --git a/src/protocol.c b/src/protocol.c index 85a4047c..31d22064 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -1,7 +1,7 @@ /* protocol.c -- handle the meta-protocol - Copyright (C) 1999,2000 Ivo Timmermans , - 2000 Guus Sliepen + Copyright (C) 1999-2001 Ivo Timmermans , + 2000,2001 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -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.71 2001/01/05 23:53:51 guus Exp $ + $Id: protocol.c,v 1.28.4.80 2001/02/25 16:34:19 guus Exp $ */ #include "config.h" @@ -31,10 +31,12 @@ #include #include #include +#include #include #include #include +#include #include @@ -196,6 +198,7 @@ int id_h(connection_t *cl) connection_t *old; unsigned short int port; char name[MAX_STRING_SIZE]; + avl_node_t *node; cp if(sscanf(cl->buffer, "%*d "MAX_STRING" %d %lx %hd", name, &cl->protocol_version, &cl->options, &port) != 4) { @@ -256,9 +259,9 @@ cp /* And uhr... cl->port just changed so we have to unlink it from the connection tree and re-insert... */ - avl_unlink(connection_tree, cl); + node = avl_unlink(connection_tree, cl); cl->port = port; - avl_insert(connection_tree, cl); + avl_insert_node(connection_tree, node); /* Read in the public key, so that we can send a challenge */ @@ -585,6 +588,7 @@ cp int ack_h(connection_t *cl) { + config_t const *cfg; connection_t *old, *p; subnet_t *subnet; avl_node_t *node, *node2; @@ -609,7 +613,7 @@ cp cl->status.active = 1; cl->status.decryptin = 1; cl->nexthop = cl; - cl->cipher_pkttype = EVP_bf_cfb(); + cl->cipher_pkttype = EVP_bf_cbc(); cl->cipher_pktkeylength = cl->cipher_pkttype->key_len + cl->cipher_pkttype->iv_len; if(debug_lvl >= DEBUG_CONNECTIONS) @@ -619,6 +623,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) @@ -660,9 +678,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; @@ -737,9 +761,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; @@ -817,7 +846,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); } @@ -899,7 +929,7 @@ cp new->nexthop = cl; new->status.active = 1; - new->cipher_pkttype = EVP_bf_cfb(); + new->cipher_pkttype = EVP_bf_cbc(); new->cipher_pktkeylength = cl->cipher_pkttype->key_len + cl->cipher_pkttype->iv_len; cp return 0; @@ -908,7 +938,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); } @@ -1013,20 +1044,20 @@ cp return 0; } -int send_error(connection_t *cl, int errno, char *errstring) +int send_error(connection_t *cl, int err, char *errstring) { cp if(!errstring) - errstring = strerror(errno); - return send_request(cl, "%d %d %s", ERROR, errno, errstring); + errstring = strerror(err); + return send_request(cl, "%d %d %s", ERROR, err, errstring); } int error_h(connection_t *cl) { - int errno; + int err; char errorstring[MAX_STRING_SIZE]; cp - if(sscanf(cl->buffer, "%*d %d "MAX_STRING, &errno, errorstring) != 2) + if(sscanf(cl->buffer, "%*d %d "MAX_STRING, &err, errorstring) != 2) { syslog(LOG_ERR, _("Got bad ERROR from %s (%s)"), cl->name, cl->hostname); @@ -1036,7 +1067,7 @@ cp if(debug_lvl >= DEBUG_ERROR) { syslog(LOG_NOTICE, _("Error message from %s (%s): %s: %s"), - cl->name, cl->hostname, strerror(errno), errorstring); + cl->name, cl->hostname, strerror(err), errorstring); } terminate_connection(cl); @@ -1058,8 +1089,6 @@ cp return 0; } -/* Keepalive routines - FIXME: needs a closer look */ - int send_ping(connection_t *cl) { cp @@ -1100,7 +1129,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(!(p->options & OPTION_INDIRECT) || from == myself) + send_request(p, "%d %s", KEY_CHANGED, from->name); } cp return 0; @@ -1257,10 +1287,65 @@ cp from->status.validkey = 1; from->status.waitingforkey = 0; + + flush_queue(from); 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) + { + if(x==0) + syslog(LOG_NOTICE, _("Connection closed by %s (%s)"), cl->name, cl->hostname); + else + if(errno==EINTR) + continue; + else + 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*) = { @@ -1270,6 +1355,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 */ @@ -1281,6 +1367,7 @@ char (*request_name[]) = { "ADD_HOST", "DEL_HOST", "ADD_SUBNET", "DEL_SUBNET", "KEY_CHANGED", "REQ_KEY", "ANS_KEY", + "PACKET", }; /* Status strings */