X-Git-Url: https://tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Fnet.c;h=18e5951bf2be5a98651b37a743d0827aaa69f7f8;hp=a42ebce43de590c42c43722c0f15eab3b1b89e7c;hb=447a43d63960802a7a29201c512246be11eb9c94;hpb=e924096f62655d711cd2d114a8d1ef0fecbb593b diff --git a/src/net.c b/src/net.c index a42ebce4..18e5951b 100644 --- a/src/net.c +++ b/src/net.c @@ -1,7 +1,7 @@ /* net.c -- most of the network code - Copyright (C) 1998,1999,2000 Ivo Timmermans , - 2000 Guus Sliepen + Copyright (C) 1998-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: net.c,v 1.35.4.89 2001/01/05 23:53:49 guus Exp $ + $Id: net.c,v 1.35.4.92 2001/01/07 20:19:29 guus Exp $ */ #include "config.h" @@ -72,10 +72,10 @@ #include #include #include +#include #include "conf.h" #include "connection.h" -#include "list.h" #include "meta.h" #include "net.h" #include "netutl.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,156 +163,38 @@ 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; } -/* - add the given packet of size s to the - queue q, be it the send or receive queue -*/ -void add_queue(packet_queue_t **q, void *packet, size_t s) -{ - queue_element_t *e; -cp - e = xmalloc(sizeof(*e)); - e->packet = xmalloc(s); - memcpy(e->packet, packet, s); - - if(!*q) - { - *q = xmalloc(sizeof(**q)); - (*q)->head = (*q)->tail = NULL; - } - - e->next = NULL; /* We insert at the tail */ - - if((*q)->tail) /* Do we have a tail? */ - { - (*q)->tail->next = e; - e->prev = (*q)->tail; - } - else /* No tail -> no head too */ - { - (*q)->head = e; - e->prev = NULL; - } - - (*q)->tail = e; -cp -} - -/* Remove a queue element */ -void del_queue(packet_queue_t **q, queue_element_t *e) -{ -cp - free(e->packet); - - if(e->next) /* There is a successor, so we are not tail */ - { - if(e->prev) /* There is a predecessor, so we are not head */ - { - e->next->prev = e->prev; - e->prev->next = e->next; - } - else /* We are head */ - { - e->next->prev = NULL; - (*q)->head = e->next; - } - } - else /* We are tail (or all alone!) */ - { - if(e->prev) /* We are not alone :) */ - { - e->prev->next = NULL; - (*q)->tail = e->prev; - } - else /* Adieu */ - { - free(*q); - *q = NULL; - } - } - - free(e); -cp -} - -/* - flush a queue by calling function for - each packet, and removing it when that - returned a zero exit code -*/ -void flush_queue(connection_t *cl, packet_queue_t **pq, - int (*function)(connection_t*,vpn_packet_t*)) -{ - queue_element_t *p, *next = NULL; -cp - for(p = (*pq)->head; p != NULL; ) - { - next = p->next; - - if(!function(cl, p->packet)) - del_queue(pq, p); - - p = next; - } - - if(debug_lvl >= DEBUG_TRAFFIC) - syslog(LOG_DEBUG, _("Queue flushed")); -cp -} - -/* - flush the send&recv queues - void because nothing goes wrong here, packets - remain in the queue if something goes wrong -*/ -void flush_queues(connection_t *cl) -{ -cp - if(cl->sq) - { - if(debug_lvl >= DEBUG_TRAFFIC) - syslog(LOG_DEBUG, _("Flushing send queue for %s (%s)"), - cl->name, cl->hostname); - flush_queue(cl, &(cl->sq), xsend); - } - - if(cl->rq) - { - if(debug_lvl >= DEBUG_TRAFFIC) - syslog(LOG_DEBUG, _("Flushing receive queue for %s (%s)"), - cl->name, cl->hostname); - flush_queue(cl, &(cl->rq), xrecv); - } -cp -} - /* send a packet to the given vpn ip. */ @@ -345,37 +227,49 @@ cp return -1; } - /* If we ourselves have indirectdata flag set, we should send only to our uplink! */ + if(!cl->status.active) + { + if(debug_lvl >= DEBUG_TRAFFIC) + syslog(LOG_INFO, _("%s (%s) is not active, dropping packet"), + cl->name, cl->hostname); + + return 0; + } - /* FIXME - check for indirection and reprogram it The Right Way(tm) this time. */ - if(!cl->status.validkey) { -/* FIXME: Don't queue until everything else is fixed. if(debug_lvl >= DEBUG_TRAFFIC) syslog(LOG_INFO, _("No valid key known yet for %s (%s), queueing packet"), cl->name, cl->hostname); - add_queue(&(cl->sq), packet, packet->len + 2); -*/ + + list_insert_tail(cl->queue, packet); + if(!cl->status.waitingforkey) send_req_key(myself, cl); /* Keys should be sent to the host running the tincd */ return 0; } - if(!cl->status.active) + /* Check if it has to go via UDP or TCP... */ +cp + if(cl->options & OPTION_TCPONLY) + return send_tcppacket(cl, packet); + else + return xsend(cl, packet); +} + +void flush_queue(connection_t *cl) +{ + list_node_t *node, *next; + + if(debug_lvl >= DEBUG_TRAFFIC) + syslog(LOG_INFO, _("Flushing queue for %s (%s)"), cl->name, cl->hostname); + + for(node = cl->queue->head; node; node = next) { -/* FIXME: Don't queue until everything else is fixed. - if(debug_lvl >= DEBUG_TRAFFIC) - syslog(LOG_INFO, _("%s (%s) is not ready, queueing packet"), - cl->name, cl->hostname); - add_queue(&(cl->sq), packet, packet->len + 2); -*/ - return 0; /* We don't want to mess up, do we? */ + next = node->next; + xsend(cl, (vpn_packet_t *)node->data); + list_delete_node(cl->queue, node); } - - /* can we send it? can we? can we? huh? */ -cp - return xsend(cl, packet); } /* @@ -808,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; @@ -907,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;