Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ambrop72/badvpn.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorambrop7 <ambrop7@1a93d707-3861-5ebc-ad3b-9740d49b5140>2013-04-22 20:16:03 +0400
committerambrop7 <ambrop7@1a93d707-3861-5ebc-ad3b-9740d49b5140>2013-04-22 20:16:03 +0400
commited6449d06af4d106ec3ca09aaf9f218362109747 (patch)
tree274310fdbc5da4f47d7c620d3c647be3f3667b0d /udpgw_client
parentc0b9b54be8c0409d6f8db7e09240afb78001639d (diff)
tun2socks: IPv6 support. Includes updated lwIP version and udpgw program.
Diffstat (limited to 'udpgw_client')
-rw-r--r--udpgw_client/UdpGwClient.c87
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)