diff options
author | ambrop7 <ambrop7@1a93d707-3861-5ebc-ad3b-9740d49b5140> | 2013-04-22 20:16:03 +0400 |
---|---|---|
committer | ambrop7 <ambrop7@1a93d707-3861-5ebc-ad3b-9740d49b5140> | 2013-04-22 20:16:03 +0400 |
commit | ed6449d06af4d106ec3ca09aaf9f218362109747 (patch) | |
tree | 274310fdbc5da4f47d7c620d3c647be3f3667b0d /udpgw_client | |
parent | c0b9b54be8c0409d6f8db7e09240afb78001639d (diff) |
tun2socks: IPv6 support. Includes updated lwIP version and udpgw program.
Diffstat (limited to 'udpgw_client')
-rw-r--r-- | udpgw_client/UdpGwClient.c | 87 |
1 files changed, 58 insertions, 29 deletions
diff --git a/udpgw_client/UdpGwClient.c b/udpgw_client/UdpGwClient.c index 8b0eff6..85d069a 100644 --- a/udpgw_client/UdpGwClient.c +++ b/udpgw_client/UdpGwClient.c @@ -39,7 +39,6 @@ #include <generated/blog_channel_UdpGwClient.h> static int uint16_comparator (void *unused, uint16_t *v1, uint16_t *v2); -static int compare_addresses (BAddr v1, BAddr v2); static int conaddr_comparator (void *unused, struct UdpGwClient_conaddr *v1, struct UdpGwClient_conaddr *v2); static void free_server (UdpGwClient *o); static void decoder_handler_error (UdpGwClient *o); @@ -60,31 +59,13 @@ static int uint16_comparator (void *unused, uint16_t *v1, uint16_t *v2) return B_COMPARE(*v1, *v2); } -static int compare_addresses (BAddr v1, BAddr v2) -{ - ASSERT(v1.type == BADDR_TYPE_IPV4) - ASSERT(v2.type == BADDR_TYPE_IPV4) - - int cmp = B_COMPARE(v1.ipv4.port, v2.ipv4.port); - if (cmp) { - return cmp; - } - - return B_COMPARE(v1.ipv4.ip, v2.ipv4.ip); -} - static int conaddr_comparator (void *unused, struct UdpGwClient_conaddr *v1, struct UdpGwClient_conaddr *v2) { - ASSERT(v1->local_addr.type == BADDR_TYPE_IPV4) - ASSERT(v1->remote_addr.type == BADDR_TYPE_IPV4) - ASSERT(v2->local_addr.type == BADDR_TYPE_IPV4) - ASSERT(v2->remote_addr.type == BADDR_TYPE_IPV4) - - int r = compare_addresses(v1->remote_addr, v2->remote_addr); + int r = BAddr_CompareOrder(&v1->remote_addr, &v2->remote_addr); if (r) { return r; } - return compare_addresses(v1->local_addr, v2->local_addr); + return BAddr_CompareOrder(&v1->local_addr, &v2->local_addr); } static void free_server (UdpGwClient *o) @@ -133,8 +114,33 @@ static void recv_interface_handler_send (UdpGwClient *o, uint8_t *data, int data memcpy(&header, data, sizeof(header)); data += sizeof(header); data_len -= sizeof(header); + uint8_t flags = ltoh8(header.flags); uint16_t conid = ltoh16(header.conid); + // parse address + BAddr remote_addr; + if ((flags & UDPGW_CLIENT_FLAG_IPV6)) { + if (data_len < sizeof(struct udpgw_addr_ipv6)) { + BLog(BLOG_ERROR, "missing ipv6 address"); + return; + } + struct udpgw_addr_ipv6 addr_ipv6; + memcpy(&addr_ipv6, data, sizeof(addr_ipv6)); + data += sizeof(addr_ipv6); + data_len -= sizeof(addr_ipv6); + BAddr_InitIPv6(&remote_addr, addr_ipv6.addr_ip, addr_ipv6.addr_port); + } else { + if (data_len < sizeof(struct udpgw_addr_ipv4)) { + BLog(BLOG_ERROR, "missing ipv4 address"); + return; + } + struct udpgw_addr_ipv4 addr_ipv4; + memcpy(&addr_ipv4, data, sizeof(addr_ipv4)); + data += sizeof(addr_ipv4); + data_len -= sizeof(addr_ipv4); + BAddr_InitIPv4(&remote_addr, addr_ipv4.addr_ip, addr_ipv4.addr_port); + } + // check remaining data if (data_len > o->udp_mtu) { BLog(BLOG_ERROR, "too much data"); @@ -149,7 +155,7 @@ static void recv_interface_handler_send (UdpGwClient *o, uint8_t *data, int data } // check remote address - if (con->conaddr.remote_addr.ipv4.port != header.addr_port || con->conaddr.remote_addr.ipv4.ip != header.addr_ip) { + if (BAddr_CompareOrder(&con->conaddr.remote_addr, &remote_addr) != 0) { BLog(BLOG_ERROR, "wrong remote address"); return; } @@ -334,20 +340,43 @@ static void connection_send (struct UdpGwClient_connection *con, uint8_t flags, BLog(BLOG_ERROR, "out of buffer"); return; } + int out_pos = 0; + + if (con->conaddr.remote_addr.type == BADDR_TYPE_IPV6) { + flags |= UDPGW_CLIENT_FLAG_IPV6; + } // write header struct udpgw_header header; header.flags = ltoh8(flags); header.conid = ltoh16(con->conid); - header.addr_ip = con->conaddr.remote_addr.ipv4.ip; - header.addr_port = con->conaddr.remote_addr.ipv4.port; - memcpy(out, &header, sizeof(header)); + memcpy(out + out_pos, &header, sizeof(header)); + out_pos += sizeof(header); + + // write address + switch (con->conaddr.remote_addr.type) { + case BADDR_TYPE_IPV4: { + struct udpgw_addr_ipv4 addr_ipv4; + addr_ipv4.addr_ip = con->conaddr.remote_addr.ipv4.ip; + addr_ipv4.addr_port = con->conaddr.remote_addr.ipv4.port; + memcpy(out + out_pos, &addr_ipv4, sizeof(addr_ipv4)); + out_pos += sizeof(addr_ipv4); + } break; + case BADDR_TYPE_IPV6: { + struct udpgw_addr_ipv6 addr_ipv6; + memcpy(addr_ipv6.addr_ip, con->conaddr.remote_addr.ipv6.ip, sizeof(addr_ipv6.addr_ip)); + addr_ipv6.addr_port = con->conaddr.remote_addr.ipv6.port; + memcpy(out + out_pos, &addr_ipv6, sizeof(addr_ipv6)); + out_pos += sizeof(addr_ipv6); + } break; + } // write packet to buffer - memcpy(out + sizeof(header), data, data_len); + memcpy(out + out_pos, data, data_len); + out_pos += data_len; // submit packet to buffer - BufferWriter_EndPacket(con->send_if, sizeof(header) + data_len); + BufferWriter_EndPacket(con->send_if, out_pos); } static struct UdpGwClient_connection * reuse_connection (UdpGwClient *o, struct UdpGwClient_conaddr conaddr) @@ -486,8 +515,8 @@ void UdpGwClient_Free (UdpGwClient *o) void UdpGwClient_SubmitPacket (UdpGwClient *o, BAddr local_addr, BAddr remote_addr, int is_dns, const uint8_t *data, int data_len) { DebugObject_Access(&o->d_obj); - ASSERT(local_addr.type == BADDR_TYPE_IPV4) - ASSERT(remote_addr.type == BADDR_TYPE_IPV4) + ASSERT(local_addr.type == BADDR_TYPE_IPV4 || local_addr.type == BADDR_TYPE_IPV6) + ASSERT(remote_addr.type == BADDR_TYPE_IPV4 || remote_addr.type == BADDR_TYPE_IPV6) ASSERT(data_len >= 0) ASSERT(data_len <= o->udp_mtu) |