X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fnet_packet.c;h=41e2521df386a18c2770e2678d0a715a6067950d;hb=69d248741bba651688b1dd080e93f887b0746f41;hp=818dd3883b3f53ddaeea9a3e6c6743cb485eeeac;hpb=82bbb6f1947bfb98a52422d7202aef331d36b1d7;p=meshlink diff --git a/src/net_packet.c b/src/net_packet.c index 818dd388..41e2521d 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -131,7 +131,6 @@ static void send_mtu_probe_handler(void *data) { memset(packet.data, 0, 14); randomize(packet.data + 14, len - 14); packet.len = len; - packet.priority = 0; n->status.broadcast = i >= 4 && n->mtuprobes <= 10 && n->prevedge; logger(DEBUG_TRAFFIC, LOG_INFO, "Sending MTU probe length %d to %s (%s)", len, n->name, n->hostname); @@ -164,7 +163,7 @@ void send_mtu_probe(node_t *n) { send_mtu_probe_handler(n); } -static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { +static void mtu_probe_h(node_t *n, vpn_packet_t *packet, uint16_t len) { logger(DEBUG_TRAFFIC, LOG_INFO, "Got MTU probe length %d from %s (%s)", packet->len, n->name, n->hostname); if(!packet->data[0]) { @@ -231,7 +230,7 @@ static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) { } } -static length_t compress_packet(uint8_t *dest, const uint8_t *source, length_t len, int level) { +static uint16_t compress_packet(uint8_t *dest, const uint8_t *source, uint16_t len, int level) { if(level == 0) { memcpy(dest, source, len); return len; @@ -252,7 +251,7 @@ static length_t compress_packet(uint8_t *dest, const uint8_t *source, length_t l return -1; } -static length_t uncompress_packet(uint8_t *dest, const uint8_t *source, length_t len, int level) { +static uint16_t uncompress_packet(uint8_t *dest, const uint8_t *source, uint16_t len, int level) { if(level == 0) { memcpy(dest, source, len); return len; @@ -285,16 +284,10 @@ static void receive_packet(node_t *n, vpn_packet_t *packet) { } static bool try_mac(node_t *n, const vpn_packet_t *inpkt) { - return sptps_verify_datagram(&n->sptps, (char *)&inpkt->seqno, inpkt->len); + return sptps_verify_datagram(&n->sptps, inpkt->data, inpkt->len); } static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { - vpn_packet_t pkt1, pkt2; - vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 }; - int nextpkt = 0; - vpn_packet_t *outpkt = pkt[0]; - size_t outlen; - if(!n->sptps.state) { if(!n->status.waitingforkey) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but we haven't exchanged keys yet", n->name, n->hostname); @@ -304,7 +297,7 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { } return; } - sptps_receive_data(&n->sptps, (char *)&inpkt->seqno, inpkt->len); + sptps_receive_data(&n->sptps, inpkt->data, inpkt->len); } void receive_tcppacket(connection_t *c, const char *buffer, int len) { @@ -314,10 +307,7 @@ void receive_tcppacket(connection_t *c, const char *buffer, int len) { return; outpkt.len = len; - if(c->options & OPTION_TCPONLY) - outpkt.priority = 0; - else - outpkt.priority = -1; + outpkt.tcp = true; memcpy(outpkt.data, buffer, len); receive_packet(c->node, &outpkt); @@ -338,35 +328,27 @@ static void send_sptps_packet(node_t *n, vpn_packet_t *origpkt) { } uint8_t type = 0; - int offset = 0; - if(!(origpkt->data[12] | origpkt->data[13])) { - sptps_send_record(&n->sptps, PKT_PROBE, (char *)origpkt->data, origpkt->len); + // If it's a probe, send it immediately without trying to compress it. + if(origpkt->probe) { + sptps_send_record(&n->sptps, PKT_PROBE, origpkt->data, origpkt->len); return; } - if(routing_mode == RMODE_ROUTER) - offset = 14; - else - type = PKT_MAC; - - if(origpkt->len < offset) - return; - vpn_packet_t outpkt; if(n->outcompression) { - int len = compress_packet(outpkt.data + offset, origpkt->data + offset, origpkt->len - offset, n->outcompression); + int len = compress_packet(outpkt.data, origpkt->data, origpkt->len, n->outcompression); if(len < 0) { logger(DEBUG_TRAFFIC, LOG_ERR, "Error while compressing packet to %s (%s)", n->name, n->hostname); - } else if(len < origpkt->len - offset) { - outpkt.len = len + offset; + } else if(len < origpkt->len) { + outpkt.len = len; origpkt = &outpkt; type |= PKT_COMPRESSED; } } - sptps_send_record(&n->sptps, type, (char *)origpkt->data + offset, origpkt->len - offset); + sptps_send_record(&n->sptps, type, origpkt->data, origpkt->len); return; } @@ -466,10 +448,6 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { vpn_packet_t *outpkt; int origlen = origpkt->len; size_t outlen; -#if defined(SOL_IP) && defined(IP_TOS) - static int priority = 0; -#endif - int origpriority = origpkt->priority; if(!n->status.reachable) { logger(DEBUG_TRAFFIC, LOG_INFO, "Trying to send UDP packet to unreachable node %s (%s)", n->name, n->hostname); @@ -543,56 +521,31 @@ bool receive_sptps_record(void *handle, uint8_t type, const char *data, uint16_t if(type == PKT_PROBE) { inpkt.len = len; + inpkt.probe = true; memcpy(inpkt.data, data, len); mtu_probe_h(from, &inpkt, len); return true; + } else { + inpkt.probe = false; } - if(type & ~(PKT_COMPRESSED | PKT_MAC)) { + if(type & ~(PKT_COMPRESSED)) { logger(DEBUG_ALWAYS, LOG_ERR, "Unexpected SPTPS record type %d len %d from %s (%s)", type, len, from->name, from->hostname); return false; } - /* Check if we have the headers we need */ - if(routing_mode != RMODE_ROUTER && !(type & PKT_MAC)) { - logger(DEBUG_TRAFFIC, LOG_ERR, "Received packet from %s (%s) without MAC header (maybe Mode is not set correctly)", from->name, from->hostname); - return false; - } else if(routing_mode == RMODE_ROUTER && (type & PKT_MAC)) { - logger(DEBUG_TRAFFIC, LOG_WARNING, "Received packet from %s (%s) with MAC header (maybe Mode is not set correctly)", from->name, from->hostname); - } - - int offset = (type & PKT_MAC) ? 0 : 14; if(type & PKT_COMPRESSED) { - length_t ulen = uncompress_packet(inpkt.data + offset, (const uint8_t *)data, len, from->incompression); + uint16_t ulen = uncompress_packet(inpkt.data, (const uint8_t *)data, len, from->incompression); if(ulen < 0) { return false; } else { - inpkt.len = ulen + offset; + inpkt.len = ulen; } if(inpkt.len > MAXSIZE) abort(); } else { - memcpy(inpkt.data + offset, data, len); - inpkt.len = len + offset; - } - - /* Generate the Ethernet packet type if necessary */ - if(offset) { - switch(inpkt.data[14] >> 4) { - case 4: - inpkt.data[12] = 0x08; - inpkt.data[13] = 0x00; - break; - case 6: - inpkt.data[12] = 0x86; - inpkt.data[13] = 0xDD; - break; - default: - logger(DEBUG_TRAFFIC, LOG_ERR, - "Unknown IP version %d while reading packet from %s (%s)", - inpkt.data[14] >> 4, from->name, from->hostname); - return false; - } + memcpy(inpkt.data, data, len); + inpkt.len = len; } receive_packet(from, &inpkt); @@ -638,31 +591,9 @@ void broadcast_packet(const node_t *from, vpn_packet_t *packet) { logger(DEBUG_TRAFFIC, LOG_INFO, "Broadcasting packet of %d bytes from %s (%s)", packet->len, from->name, from->hostname); - switch(broadcast_mode) { - // In MST mode, broadcast packets travel via the Minimum Spanning Tree. - // This guarantees all nodes receive the broadcast packet, and - // usually distributes the sending of broadcast packets over all nodes. - case BMODE_MST: - for list_each(connection_t, c, connection_list) - if(c->status.active && c->status.mst && c != from->nexthop->connection) - send_packet(c->node, packet); - break; - - // In direct mode, we send copies to each node we know of. - // However, this only reaches nodes that can be reached in a single hop. - // We don't have enough information to forward broadcast packets in this case. - case BMODE_DIRECT: - if(from != myself) - break; - - for splay_each(node_t, n, node_tree) - if(n->status.reachable && n != myself && ((n->via == myself && n->nexthop == n) || n->via == n)) - send_packet(n, packet); - break; - - default: - break; - } + for list_each(connection_t, c, connection_list) + if(c->status.active && c->status.mst && c != from->nexthop->connection) + send_packet(c->node, packet); } static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) { @@ -703,7 +634,7 @@ void handle_incoming_vpn_data(void *data, int flags) { node_t *n; int len; - len = recvfrom(ls->udp.fd, (char *) &pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen); + len = recvfrom(ls->udp.fd, pkt.data, MAXSIZE, 0, &from.sa, &fromlen); if(len <= 0 || len > MAXSIZE) { if(!sockwouldblock(sockerrno))