mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2024-11-22 17:39:53 +03:00
Cedar: Make use of IP address reported by NAT-T server for UDP acceleration
Before this commit, the IP address reported by the NAT-T server was immediately discarded. That's because the peer should be accessible via the IP address used to establish the TCP connection. User "domosekai" (https://www.domosekai.com) pointed out that the NAT-T IP address should be taken into account. In his case it's required due to his broadband carrier's NAT causing TCP and UDP to have different external IPs. Co-authored-by: domosekai <54519668+domosekai@users.noreply.github.com>
This commit is contained in:
parent
192083e7c4
commit
d4d15b66d3
@ -886,8 +886,9 @@ void SendKeepAlive(CONNECTION *c, TCPSOCK *ts)
|
|||||||
UINT size, i, num;
|
UINT size, i, num;
|
||||||
UINT size_be;
|
UINT size_be;
|
||||||
SESSION *s;
|
SESSION *s;
|
||||||
|
UDP_ACCEL *udp_accel;
|
||||||
UCHAR *buf;
|
UCHAR *buf;
|
||||||
bool insert_natt_port = false;
|
bool insert_natt_port = false, insert_natt_ip = false;
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
if (c == NULL || ts == NULL)
|
if (c == NULL || ts == NULL)
|
||||||
{
|
{
|
||||||
@ -895,33 +896,61 @@ void SendKeepAlive(CONNECTION *c, TCPSOCK *ts)
|
|||||||
}
|
}
|
||||||
|
|
||||||
s = c->Session;
|
s = c->Session;
|
||||||
|
if (s == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
udp_accel = s->UdpAccel;
|
||||||
|
|
||||||
size = rand() % MAX_KEEPALIVE_SIZE;
|
size = rand() % MAX_KEEPALIVE_SIZE;
|
||||||
num = KEEP_ALIVE_MAGIC;
|
num = KEEP_ALIVE_MAGIC;
|
||||||
|
|
||||||
if (s != NULL && s->UseUdpAcceleration && s->UdpAccel != NULL)
|
if (s->UseUdpAcceleration && udp_accel != NULL)
|
||||||
{
|
{
|
||||||
if (s->UdpAccel->MyPortByNatTServer != 0)
|
if (udp_accel->MyPortNatT != 0)
|
||||||
{
|
{
|
||||||
size = MAX(size, (StrLen(UDP_NAT_T_PORT_SIGNATURE_IN_KEEP_ALIVE) + sizeof(USHORT)));
|
size = MAX(size, (StrLen(UDP_NAT_T_PORT_SIGNATURE_IN_KEEP_ALIVE) + sizeof(USHORT)));
|
||||||
|
|
||||||
insert_natt_port = true;
|
insert_natt_port = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsZeroIP(&udp_accel->MyIpNatT) == false)
|
||||||
|
{
|
||||||
|
size = MAX(size, (StrLen(UDP_NAT_T_IP_SIGNATURE_IN_KEEP_ALIVE) + sizeof(udp_accel->MyIpNatT.address)));
|
||||||
|
|
||||||
|
insert_natt_ip = true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = MallocFast(size);
|
buf = MallocFast(size);
|
||||||
|
|
||||||
for (i = 0;i < size;i++)
|
for (i = 0; i < size; ++i)
|
||||||
{
|
{
|
||||||
buf[i] = rand();
|
buf[i] = rand();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UCHAR *seek = buf;
|
||||||
|
|
||||||
if (insert_natt_port)
|
if (insert_natt_port)
|
||||||
{
|
{
|
||||||
USHORT myport = Endian16((USHORT)s->UdpAccel->MyPortByNatTServer);
|
const UINT nat_t_port_sig_size = StrLen(UDP_NAT_T_PORT_SIGNATURE_IN_KEEP_ALIVE);
|
||||||
|
const USHORT port = Endian16(udp_accel->MyPortNatT);
|
||||||
|
|
||||||
Copy(buf, UDP_NAT_T_PORT_SIGNATURE_IN_KEEP_ALIVE, StrLen(UDP_NAT_T_PORT_SIGNATURE_IN_KEEP_ALIVE));
|
Copy(buf, UDP_NAT_T_PORT_SIGNATURE_IN_KEEP_ALIVE, nat_t_port_sig_size);
|
||||||
Copy(buf + StrLen(UDP_NAT_T_PORT_SIGNATURE_IN_KEEP_ALIVE), &myport, sizeof(USHORT));
|
seek += nat_t_port_sig_size;
|
||||||
|
Copy(seek, &port, sizeof(port));
|
||||||
|
seek += sizeof(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (insert_natt_ip)
|
||||||
|
{
|
||||||
|
const UINT nat_t_ip_sig_size = StrLen(UDP_NAT_T_IP_SIGNATURE_IN_KEEP_ALIVE);
|
||||||
|
|
||||||
|
Copy(seek, UDP_NAT_T_IP_SIGNATURE_IN_KEEP_ALIVE, nat_t_ip_sig_size);
|
||||||
|
seek += nat_t_ip_sig_size;
|
||||||
|
Copy(seek, udp_accel->MyIpNatT.address, sizeof(udp_accel->MyIpNatT.address));
|
||||||
}
|
}
|
||||||
|
|
||||||
num = Endian32(num);
|
num = Endian32(num);
|
||||||
@ -1003,7 +1032,7 @@ void ConnectionSend(CONNECTION *c, UINT64 now)
|
|||||||
{
|
{
|
||||||
// Processing of KeepAlive
|
// Processing of KeepAlive
|
||||||
if (now >= tcpsock->NextKeepAliveTime || tcpsock->NextKeepAliveTime == 0 ||
|
if (now >= tcpsock->NextKeepAliveTime || tcpsock->NextKeepAliveTime == 0 ||
|
||||||
(s->UseUdpAcceleration && s->UdpAccel != NULL && s->UdpAccel->MyPortByNatTServerChanged))
|
(s->UseUdpAcceleration && s->UdpAccel != NULL && s->UdpAccel->MyIpOrPortNatTChanged))
|
||||||
{
|
{
|
||||||
// Send the KeepAlive
|
// Send the KeepAlive
|
||||||
SendKeepAlive(c, tcpsock);
|
SendKeepAlive(c, tcpsock);
|
||||||
@ -1011,7 +1040,7 @@ void ConnectionSend(CONNECTION *c, UINT64 now)
|
|||||||
|
|
||||||
if (s->UseUdpAcceleration && s->UdpAccel != NULL)
|
if (s->UseUdpAcceleration && s->UdpAccel != NULL)
|
||||||
{
|
{
|
||||||
s->UdpAccel->MyPortByNatTServerChanged = false;
|
s->UdpAccel->MyIpOrPortNatTChanged = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2185,30 +2214,50 @@ DISCONNECT_THIS_TCP:
|
|||||||
ts->Mode = 0;
|
ts->Mode = 0;
|
||||||
sz = ts->NextBlockSize;
|
sz = ts->NextBlockSize;
|
||||||
|
|
||||||
if (sz >= (StrLen(UDP_NAT_T_PORT_SIGNATURE_IN_KEEP_ALIVE) + sizeof(USHORT)))
|
|
||||||
{
|
|
||||||
UCHAR *keep_alive_buffer = FifoPtr(ts->RecvFifo);
|
|
||||||
|
|
||||||
if (Cmp(keep_alive_buffer, UDP_NAT_T_PORT_SIGNATURE_IN_KEEP_ALIVE, StrLen(UDP_NAT_T_PORT_SIGNATURE_IN_KEEP_ALIVE)) == 0)
|
|
||||||
{
|
|
||||||
USHORT us = READ_USHORT(keep_alive_buffer + StrLen(UDP_NAT_T_PORT_SIGNATURE_IN_KEEP_ALIVE));
|
|
||||||
|
|
||||||
if (us != 0)
|
|
||||||
{
|
|
||||||
if (s->UseUdpAcceleration && s->UdpAccel != NULL)
|
if (s->UseUdpAcceleration && s->UdpAccel != NULL)
|
||||||
{
|
{
|
||||||
UINT port = (UINT)us;
|
const UCHAR *keep_alive_buffer = FifoPtr(ts->RecvFifo);
|
||||||
|
const UINT nat_t_ip_sig_size = StrLen(UDP_NAT_T_IP_SIGNATURE_IN_KEEP_ALIVE);
|
||||||
|
const UINT nat_t_port_sig_size = StrLen(UDP_NAT_T_PORT_SIGNATURE_IN_KEEP_ALIVE);
|
||||||
|
UINT cur_size = sz;
|
||||||
|
|
||||||
if (s->UdpAccel->YourPortByNatTServer != port)
|
if (cur_size >= nat_t_port_sig_size + sizeof(USHORT))
|
||||||
{
|
{
|
||||||
s->UdpAccel->YourPortByNatTServer = port;
|
if (Cmp(keep_alive_buffer, UDP_NAT_T_PORT_SIGNATURE_IN_KEEP_ALIVE, nat_t_port_sig_size) == 0)
|
||||||
s->UdpAccel->YourPortByNatTServerChanged = true;
|
{
|
||||||
|
cur_size -= nat_t_port_sig_size;
|
||||||
|
keep_alive_buffer += nat_t_port_sig_size;
|
||||||
|
|
||||||
Debug("s->UdpAccel->YourPortByNatTServer: %u\n",
|
const USHORT port = READ_USHORT(keep_alive_buffer);
|
||||||
s->UdpAccel->YourPortByNatTServer);
|
cur_size -= sizeof(USHORT);
|
||||||
|
keep_alive_buffer += sizeof(USHORT);
|
||||||
|
|
||||||
|
if (port && s->UdpAccel->YourPortNatT != port)
|
||||||
|
{
|
||||||
|
s->UdpAccel->YourPortNatT = port;
|
||||||
|
s->UdpAccel->YourIpOrPortNatTChanged = true;
|
||||||
|
|
||||||
|
Debug("ConnectionReceive(): New peer NAT-T port: %u\n", port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cur_size >= nat_t_ip_sig_size + sizeof(s->UdpAccel->YourIpNatT.address))
|
||||||
|
{
|
||||||
|
if (Cmp(keep_alive_buffer, UDP_NAT_T_IP_SIGNATURE_IN_KEEP_ALIVE, nat_t_ip_sig_size) == 0)
|
||||||
|
{
|
||||||
|
keep_alive_buffer += nat_t_ip_sig_size;
|
||||||
|
|
||||||
|
IP ip;
|
||||||
|
SetIP6(&ip, keep_alive_buffer);
|
||||||
|
if (IsZeroIP(&ip) == false && CmpIpAddr(&s->UdpAccel->YourIpNatT, &ip) != 0)
|
||||||
|
{
|
||||||
|
Copy(&s->UdpAccel->YourIpNatT, &ip, sizeof(s->UdpAccel->YourIpNatT));
|
||||||
|
s->UdpAccel->YourIpOrPortNatTChanged = true;
|
||||||
|
|
||||||
|
Debug("ConnectionReceive(): New peer NAT-T IP: %r\n", &ip);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3001,7 +3001,7 @@ bool ServerAccept(CONNECTION *c)
|
|||||||
|
|
||||||
if (UdpAccelInitServer(s->UdpAccel,
|
if (UdpAccelInitServer(s->UdpAccel,
|
||||||
s->UdpAccel->Version == 2 ? udp_acceleration_client_key_v2 : udp_acceleration_client_key,
|
s->UdpAccel->Version == 2 ? udp_acceleration_client_key_v2 : udp_acceleration_client_key,
|
||||||
&udp_acceleration_client_ip, udp_acceleration_client_port, &c->FirstSock->RemoteIP) == false)
|
&c->FirstSock->RemoteIP, &udp_acceleration_client_ip, udp_acceleration_client_port) == false)
|
||||||
{
|
{
|
||||||
Debug("UdpAccelInitServer Failed.\n");
|
Debug("UdpAccelInitServer Failed.\n");
|
||||||
s->UseUdpAcceleration = false;
|
s->UseUdpAcceleration = false;
|
||||||
@ -4987,8 +4987,8 @@ REDIRECTED:
|
|||||||
|
|
||||||
if (UdpAccelInitClient(sess->UdpAccel,
|
if (UdpAccelInitClient(sess->UdpAccel,
|
||||||
sess->UdpAccel->Version == 2 ? udp_acceleration_server_key_v2 : udp_acceleration_server_key,
|
sess->UdpAccel->Version == 2 ? udp_acceleration_server_key_v2 : udp_acceleration_server_key,
|
||||||
&udp_acceleration_server_ip, udp_acceleration_server_port,
|
&remote_ip, &udp_acceleration_server_ip, udp_acceleration_server_port,
|
||||||
server_cookie, client_cookie, &remote_ip) == false)
|
server_cookie, client_cookie) == false)
|
||||||
{
|
{
|
||||||
Debug("UdpAccelInitClient failed.\n");
|
Debug("UdpAccelInitClient failed.\n");
|
||||||
}
|
}
|
||||||
|
@ -63,33 +63,30 @@ void UdpAccelPoll(UDP_ACCEL *a)
|
|||||||
if (a->UseUdpIpQuery && a->UdpIpQueryPacketSize >= 8 && CmpIpAddr(&a->UdpIpQueryHost, &src_ip) == 0 &&
|
if (a->UseUdpIpQuery && a->UdpIpQueryPacketSize >= 8 && CmpIpAddr(&a->UdpIpQueryHost, &src_ip) == 0 &&
|
||||||
src_port == a->UdpIpQueryPort)
|
src_port == a->UdpIpQueryPort)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
// Receive a response of the query for IP and port number
|
// Receive a response of the query for IP and port number
|
||||||
IP my_ip = {0};
|
IP my_ip = {0};
|
||||||
UINT myport = 0;
|
UINT myport = 0;
|
||||||
BUF *b = MemToBuf(a->UdpIpQueryPacketData, a->UdpIpQueryPacketSize);
|
BUF *b = MemToBuf(a->UdpIpQueryPacketData, a->UdpIpQueryPacketSize);
|
||||||
|
|
||||||
|
|
||||||
FreeBuf(b);
|
FreeBuf(b);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
else if (IsZeroIp(&nat_t_ip) == false && CmpIpAddr(&nat_t_ip, &src_ip) == 0 &&
|
else if (IsZeroIp(&nat_t_ip) == false && CmpIpAddr(&nat_t_ip, &src_ip) == 0 &&
|
||||||
src_port == UDP_NAT_T_PORT)
|
src_port == UDP_NAT_T_PORT)
|
||||||
{
|
{
|
||||||
// Receive a response from the NAT-T server
|
// Receive a response from the NAT-T server
|
||||||
IP my_ip;
|
IP ip;
|
||||||
UINT myport;
|
UINT port;
|
||||||
|
if (RUDPParseIPAndPortStr(tmp, ret, &ip, &port))
|
||||||
|
{
|
||||||
|
if (a->MyPortNatT != port && port >= 1 && port <= 65535)
|
||||||
|
{
|
||||||
|
Debug("NAT-T: MyIP = %r, MyPort = %hu\n", &ip, port);
|
||||||
|
|
||||||
if (RUDPParseIPAndPortStr(tmp, ret, &my_ip, &myport))
|
|
||||||
{
|
|
||||||
if (myport >= 1 && myport <= 65535)
|
|
||||||
{
|
|
||||||
if (a->MyPortByNatTServer != myport)
|
|
||||||
{
|
|
||||||
a->MyPortByNatTServer = myport;
|
|
||||||
a->MyPortByNatTServerChanged = true;
|
|
||||||
a->CommToNatT_NumFail = 0;
|
a->CommToNatT_NumFail = 0;
|
||||||
|
Copy(&a->MyIpNatT, &ip, sizeof(a->MyIpNatT));
|
||||||
Debug("NAT-T: MyPort = %u\n", myport);
|
a->MyPortNatT = port;
|
||||||
}
|
a->MyIpOrPortNatTChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -175,9 +172,9 @@ void UdpAccelPoll(UDP_ACCEL *a)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send a Keep-Alive packet
|
// Send a Keep-Alive packet
|
||||||
if (a->NextSendKeepAlive == 0 || (a->NextSendKeepAlive <= a->Now) || a->YourPortByNatTServerChanged)
|
if (a->NextSendKeepAlive == 0 || (a->NextSendKeepAlive <= a->Now) || a->YourIpOrPortNatTChanged)
|
||||||
{
|
{
|
||||||
a->YourPortByNatTServerChanged = false;
|
a->YourIpOrPortNatTChanged = false;
|
||||||
|
|
||||||
if (UdpAccelIsSendReady(a, false))
|
if (UdpAccelIsSendReady(a, false))
|
||||||
{
|
{
|
||||||
@ -219,7 +216,7 @@ void UdpAccelPoll(UDP_ACCEL *a)
|
|||||||
//PACK *p = NewPack();
|
//PACK *p = NewPack();
|
||||||
//BUF *b;
|
//BUF *b;
|
||||||
|
|
||||||
if (a->MyPortByNatTServer != 0)
|
if (a->MyPortNatT != 0)
|
||||||
{
|
{
|
||||||
rand_interval = GenRandInterval(UDP_NAT_T_INTERVAL_MIN, UDP_NAT_T_INTERVAL_MAX);
|
rand_interval = GenRandInterval(UDP_NAT_T_INTERVAL_MIN, UDP_NAT_T_INTERVAL_MAX);
|
||||||
}
|
}
|
||||||
@ -459,55 +456,65 @@ void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, UCHAR flag, UINT ma
|
|||||||
|
|
||||||
SetSockHighPriority(a->UdpSock, high_priority);
|
SetSockHighPriority(a->UdpSock, high_priority);
|
||||||
|
|
||||||
ret = SendTo(a->UdpSock, &a->YourIp, a->YourPort, buffer, size);
|
if (SendTo(a->UdpSock, &a->YourIp, a->YourPort, buffer, size) == 0)
|
||||||
if (ret == 0 && a->UdpSock->IgnoreSendErr == false)
|
{
|
||||||
|
Debug("UdpAccelSend(): SendTo() failed! IP: %r, port: %u, size: %u\n", &a->YourIp, a->YourPort, size);
|
||||||
|
if (a->UdpSock->IgnoreSendErr == false)
|
||||||
{
|
{
|
||||||
a->FatalError = true;
|
a->FatalError = true;
|
||||||
Debug("UdpAccelSend(): SendTo() failed! IP: %r, port: %u, size: %u\n", &a->YourIp, a->YourPort, size);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (data_size > 0 || UdpAccelIsSendReady(a, true))
|
if (data_size > 0 || UdpAccelIsSendReady(a, true))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a->YourPortByNatTServer != 0 && a->YourPortByNatTServer != a->YourPort)
|
Debug("UdpAccelSend(): Peer has not replied in a while, sending keep-alive packet to alt destinations...\n");
|
||||||
|
|
||||||
|
IP *ips[3];
|
||||||
|
ips[0] = &a->YourIp;
|
||||||
|
ips[1] = CmpIpAddr(&a->YourIpReported, &a->YourIp) == 0 ? NULL : &a->YourIpReported;
|
||||||
|
ips[2] = CmpIpAddr(&a->YourIpNatT, &a->YourIp) == 0 || CmpIpAddr(&a->YourIpNatT, &a->YourIpReported) == 0 ? NULL : &a->YourIpNatT;
|
||||||
|
|
||||||
|
USHORT ports[3];
|
||||||
|
ports[0] = a->YourPort;
|
||||||
|
ports[1] = a->YourPortReported == a->YourPort ? 0 : a->YourPortReported;
|
||||||
|
ports[2] = a->YourPortNatT == a->YourPort || a->YourPortNatT == a->YourPortReported ? 0 : a->YourPortNatT;
|
||||||
|
|
||||||
|
for (BYTE i = 0; i < sizeof(ips) / sizeof(ips[0]); ++i)
|
||||||
{
|
{
|
||||||
ret = SendTo(a->UdpSock, &a->YourIp, a->YourPortByNatTServer, buffer, size);
|
if (IsZeroIP(ips[i]))
|
||||||
if (ret == 0 && a->UdpSock->IgnoreSendErr == false)
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (BYTE j = 0; j < sizeof(ports) / sizeof(ports[0]); ++j)
|
||||||
|
{
|
||||||
|
if (ports[j] == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CmpIpAddr(ips[i], &a->YourIp) == 0 && ports[j] == a->YourPort)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SendTo(a->UdpSock, ips[i], ports[j], buffer, size) == 0)
|
||||||
|
{
|
||||||
|
Debug("UdpAccelSend(): SendTo() failed! IP: %r, port: %u, size: %u\n", ips[i], ports[j], size);
|
||||||
|
if (a->UdpSock->IgnoreSendErr == false)
|
||||||
{
|
{
|
||||||
a->FatalError = true;
|
a->FatalError = true;
|
||||||
Debug("UdpAccelSend(): SendTo() failed! IP: %r, port: %u, size: %u\n", &a->YourIp, a->YourPortByNatTServer, size);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UdpAccelIsSendReady(a, true))
|
if (UdpAccelIsSendReady(a, true))
|
||||||
{
|
{
|
||||||
return;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
if (IsZeroIP(&a->YourIp2) == false && CmpIpAddr(&a->YourIp, &a->YourIp2) != 0)
|
|
||||||
{
|
|
||||||
// We sent the packet, but the remote host didn't reply.
|
|
||||||
// It may be behind a NAT, let's try to send the packet to the alternative IP address.
|
|
||||||
ret = SendTo(a->UdpSock, &a->YourIp2, a->YourPort, buffer, size);
|
|
||||||
if (ret == 0 && a->UdpSock->IgnoreSendErr == false)
|
|
||||||
{
|
|
||||||
a->FatalError = true;
|
|
||||||
Debug("UdpAccelSend(): SendTo() failed! IP: %r, port: %u, size: %u\n", &a->YourIp2, a->YourPort, size);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a->YourPortByNatTServer != 0 && a->YourPortByNatTServer != a->YourPort)
|
|
||||||
{
|
|
||||||
ret = SendTo(a->UdpSock, &a->YourIp2, a->YourPortByNatTServer, buffer, size);
|
|
||||||
if (ret == 0 && a->UdpSock->IgnoreSendErr == false)
|
|
||||||
{
|
|
||||||
a->FatalError = true;
|
|
||||||
Debug("UdpAccelSend(): SendTo() failed! IP: %r, port: %u, size: %u\n", &a->YourIp2, a->YourPortByNatTServer, size);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -810,19 +817,18 @@ void UdpAccelSetTick(UDP_ACCEL *a, UINT64 tick64)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the server-side
|
// Initialize the server-side
|
||||||
bool UdpAccelInitServer(UDP_ACCEL *a, UCHAR *client_key, IP *client_ip, UINT client_port, IP *client_ip_2)
|
bool UdpAccelInitServer(UDP_ACCEL *a, UCHAR *key, IP *detected_ip, IP *reported_ip, USHORT port)
|
||||||
{
|
{
|
||||||
char tmp[MAX_SIZE];
|
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
if (a == NULL || client_key == NULL)
|
if (a == NULL || key == NULL || detected_ip == NULL || port == 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
IPToStr(tmp, sizeof(tmp), client_ip);
|
Debug("UdpAccelInitServer(): Version: %u, detected_ip: %r, reported_ip: %r, port: %hu, YourCookie: %u, MyCookie: %u\n",
|
||||||
Debug("UdpAccelInitServer(): version: %u, client IP: %s, client port: %u, server cookie: %u, client cookie: %u\n", a->Version, tmp, client_port, a->MyCookie, a->YourCookie);
|
a->Version, detected_ip, reported_ip, port, a->YourCookie, a->MyCookie);
|
||||||
|
|
||||||
if (IsIP6(client_ip) != a->IsIPv6)
|
if (IsIP6(detected_ip) != a->IsIPv6)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -833,16 +839,17 @@ bool UdpAccelInitServer(UDP_ACCEL *a, UCHAR *client_key, IP *client_ip, UINT cli
|
|||||||
a->CipherDecrypt = NewCipher("ChaCha20-Poly1305");
|
a->CipherDecrypt = NewCipher("ChaCha20-Poly1305");
|
||||||
|
|
||||||
SetCipherKey(a->CipherEncrypt, a->MyKey_V2, true);
|
SetCipherKey(a->CipherEncrypt, a->MyKey_V2, true);
|
||||||
SetCipherKey(a->CipherDecrypt, client_key, false);
|
SetCipherKey(a->CipherDecrypt, key, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Copy(a->YourKey, client_key, sizeof(a->YourKey));
|
Copy(a->YourKey, key, sizeof(a->YourKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
Copy(&a->YourIp, client_ip, sizeof(IP));
|
Copy(&a->YourIp, detected_ip, sizeof(a->YourIp));
|
||||||
Copy(&a->YourIp2, client_ip_2, sizeof(IP));
|
Copy(&a->YourIpReported, reported_ip, sizeof(a->YourIpReported));
|
||||||
a->YourPort = client_port;
|
|
||||||
|
a->YourPort = a->YourPortReported = port;
|
||||||
|
|
||||||
a->Now = Tick64();
|
a->Now = Tick64();
|
||||||
|
|
||||||
@ -852,19 +859,18 @@ bool UdpAccelInitServer(UDP_ACCEL *a, UCHAR *client_key, IP *client_ip, UINT cli
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the client-side
|
// Initialize the client-side
|
||||||
bool UdpAccelInitClient(UDP_ACCEL *a, UCHAR *server_key, IP *server_ip, UINT server_port, UINT server_cookie, UINT client_cookie, IP *server_ip_2)
|
bool UdpAccelInitClient(UDP_ACCEL *a, UCHAR *key, IP *detected_ip, IP *reported_ip, USHORT port, UINT cookie, UINT my_cookie)
|
||||||
{
|
{
|
||||||
char tmp[MAX_SIZE];
|
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
if (a == NULL || server_key == NULL || server_ip == NULL || server_port == 0)
|
if (a == NULL || key == NULL || detected_ip == NULL || port == 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
IPToStr(tmp, sizeof(tmp), server_ip);
|
Debug("UdpAccelInitClient(): Version: %u, detected_ip: %s, reported_ip: %s, port: %hu, cookie: %u, my_cookie: %u\n",
|
||||||
Debug("UdpAccelInitClient(): version: %u, client IP: %s, client port: %u, server cookie: %u, client cookie: %u\n", a->Version, tmp, server_port, server_cookie, client_cookie);
|
a->Version, detected_ip, reported_ip, port, cookie, my_cookie);
|
||||||
|
|
||||||
if (IsIP6(server_ip) != a->IsIPv6)
|
if (IsIP6(detected_ip) != a->IsIPv6)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -875,21 +881,22 @@ bool UdpAccelInitClient(UDP_ACCEL *a, UCHAR *server_key, IP *server_ip, UINT ser
|
|||||||
a->CipherDecrypt = NewCipher("ChaCha20-Poly1305");
|
a->CipherDecrypt = NewCipher("ChaCha20-Poly1305");
|
||||||
|
|
||||||
SetCipherKey(a->CipherEncrypt, a->MyKey_V2, true);
|
SetCipherKey(a->CipherEncrypt, a->MyKey_V2, true);
|
||||||
SetCipherKey(a->CipherDecrypt, server_key, false);
|
SetCipherKey(a->CipherDecrypt, key, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Copy(a->YourKey, server_key, sizeof(a->YourKey));
|
Copy(a->YourKey, key, sizeof(a->YourKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
Copy(&a->YourIp, server_ip, sizeof(IP));
|
Copy(&a->YourIp, detected_ip, sizeof(a->YourIp));
|
||||||
Copy(&a->YourIp2, server_ip_2, sizeof(IP));
|
Copy(&a->YourIpReported, reported_ip, sizeof(a->YourIpReported));
|
||||||
a->YourPort = server_port;
|
|
||||||
|
a->YourPort = a->YourPortReported = port;
|
||||||
|
|
||||||
a->Now = Tick64();
|
a->Now = Tick64();
|
||||||
|
|
||||||
a->MyCookie = client_cookie;
|
a->MyCookie = my_cookie;
|
||||||
a->YourCookie = server_cookie;
|
a->YourCookie = cookie;
|
||||||
|
|
||||||
a->Inited = true;
|
a->Inited = true;
|
||||||
|
|
||||||
@ -978,7 +985,7 @@ UDP_ACCEL *NewUdpAccel(CEDAR *cedar, IP *ip, bool client_mode, bool random_port,
|
|||||||
Rand(a->MyKey, sizeof(a->MyKey));
|
Rand(a->MyKey, sizeof(a->MyKey));
|
||||||
Rand(a->MyKey_V2, sizeof(a->MyKey_V2));
|
Rand(a->MyKey_V2, sizeof(a->MyKey_V2));
|
||||||
|
|
||||||
Copy(&a->MyIp, ip, sizeof(IP));
|
Copy(&a->MyIp, ip, sizeof(a->MyIp));
|
||||||
a->MyPort = s->LocalPort;
|
a->MyPort = s->LocalPort;
|
||||||
|
|
||||||
a->IsIPv6 = IsIP6(ip);
|
a->IsIPv6 = IsIP6(ip);
|
||||||
|
@ -43,7 +43,8 @@
|
|||||||
#define UDP_SERVER_PORT_LOWER 40000 // Minimum port
|
#define UDP_SERVER_PORT_LOWER 40000 // Minimum port
|
||||||
#define UDP_SERVER_PORT_HIGHER 44999 // Maximum port
|
#define UDP_SERVER_PORT_HIGHER 44999 // Maximum port
|
||||||
|
|
||||||
// NAT-T port signature to be embedded in the Keep Alive of the session
|
// NAT-T signatures to be embedded in the Keep Alive of the session
|
||||||
|
#define UDP_NAT_T_IP_SIGNATURE_IN_KEEP_ALIVE "NATT_MY_IP"
|
||||||
#define UDP_NAT_T_PORT_SIGNATURE_IN_KEEP_ALIVE "NATT_MY_PORT"
|
#define UDP_NAT_T_PORT_SIGNATURE_IN_KEEP_ALIVE "NATT_MY_PORT"
|
||||||
|
|
||||||
// UDP Acceleration Mode
|
// UDP Acceleration Mode
|
||||||
@ -59,11 +60,18 @@ struct UDP_ACCEL
|
|||||||
UCHAR MyKey[UDP_ACCELERATION_COMMON_KEY_SIZE_V1]; // Send-direction common key
|
UCHAR MyKey[UDP_ACCELERATION_COMMON_KEY_SIZE_V1]; // Send-direction common key
|
||||||
UCHAR YourKey[UDP_ACCELERATION_COMMON_KEY_SIZE_V1]; // Receive-direction common key
|
UCHAR YourKey[UDP_ACCELERATION_COMMON_KEY_SIZE_V1]; // Receive-direction common key
|
||||||
SOCK *UdpSock; // UDP socket
|
SOCK *UdpSock; // UDP socket
|
||||||
UINT MyPort; // My port number
|
|
||||||
UINT YourPort; // Port number of the other party
|
|
||||||
IP MyIp; // My IP address
|
IP MyIp; // My IP address
|
||||||
IP YourIp; // IP address of the other party
|
IP MyIpNatT; // My IP address, found via the NAT-T server
|
||||||
IP YourIp2; // IP address of the other party (second)
|
USHORT MyPort; // My port number
|
||||||
|
USHORT MyPortNatT; // My port number, found via the NAT-T server
|
||||||
|
bool MyIpOrPortNatTChanged; // NAT-T server reported a new IP or port for me
|
||||||
|
IP YourIp; // IP address of the peer (current)
|
||||||
|
IP YourIpReported; // IP address of the peer (reported)
|
||||||
|
IP YourIpNatT; // IP address of the peer, found via the NAT-T server
|
||||||
|
USHORT YourPort; // Port number of the peer (current)
|
||||||
|
USHORT YourPortReported; // Port number of the peer (reported)
|
||||||
|
USHORT YourPortNatT; // Port number of the peer, found via the NAT-T server
|
||||||
|
bool YourIpOrPortNatTChanged; // NAT-T server reported a new IP or port for the peer
|
||||||
bool IsIPv6; // Whether it's an IPv6
|
bool IsIPv6; // Whether it's an IPv6
|
||||||
UCHAR TmpBuf[UDP_ACCELERATION_TMP_BUF_SIZE]; // Temporary buffer
|
UCHAR TmpBuf[UDP_ACCELERATION_TMP_BUF_SIZE]; // Temporary buffer
|
||||||
UINT64 LastRecvYourTick; // Opponent's tick value of the last reception
|
UINT64 LastRecvYourTick; // Opponent's tick value of the last reception
|
||||||
@ -87,10 +95,6 @@ struct UDP_ACCEL
|
|||||||
EVENT *NatT_HaltEvent; // Halting event of IP address acquisition thread of NAT-T server
|
EVENT *NatT_HaltEvent; // Halting event of IP address acquisition thread of NAT-T server
|
||||||
UINT64 NextPerformNatTTick; // Time to communicate with NAT-T server next time
|
UINT64 NextPerformNatTTick; // Time to communicate with NAT-T server next time
|
||||||
UINT CommToNatT_NumFail; // Number of failures to communicate with NAT-T server
|
UINT CommToNatT_NumFail; // Number of failures to communicate with NAT-T server
|
||||||
UINT MyPortByNatTServer; // Self port number which is received from the NAT-T server
|
|
||||||
bool MyPortByNatTServerChanged; // The self port number which is received from the NAT-T server changes
|
|
||||||
UINT YourPortByNatTServer; // Port number of the opponent that was found via the NAT-T server
|
|
||||||
bool YourPortByNatTServerChanged; // Port number of the opponent that was found via the NAT-T server has been changed
|
|
||||||
bool FatalError; // A fatal error occurred
|
bool FatalError; // A fatal error occurred
|
||||||
bool NatT_IP_Changed; // IP address of the NAT-T server has changed
|
bool NatT_IP_Changed; // IP address of the NAT-T server has changed
|
||||||
UINT64 NatT_TranId; // Transaction ID to be exchanged with the NAT-T server
|
UINT64 NatT_TranId; // Transaction ID to be exchanged with the NAT-T server
|
||||||
@ -114,8 +118,8 @@ struct UDP_ACCEL
|
|||||||
// Function prototype
|
// Function prototype
|
||||||
UDP_ACCEL *NewUdpAccel(CEDAR *cedar, IP *ip, bool client_mode, bool random_port, bool no_nat_t);
|
UDP_ACCEL *NewUdpAccel(CEDAR *cedar, IP *ip, bool client_mode, bool random_port, bool no_nat_t);
|
||||||
void FreeUdpAccel(UDP_ACCEL *a);
|
void FreeUdpAccel(UDP_ACCEL *a);
|
||||||
bool UdpAccelInitClient(UDP_ACCEL *a, UCHAR *server_key, IP *server_ip, UINT server_port, UINT server_cookie, UINT client_cookie, IP *server_ip_2);
|
bool UdpAccelInitClient(UDP_ACCEL *a, UCHAR *key, IP *detected_ip, IP *reported_ip, USHORT port, UINT cookie, UINT my_cookie);
|
||||||
bool UdpAccelInitServer(UDP_ACCEL *a, UCHAR *client_key, IP *client_ip, UINT client_port, IP *client_ip_2);
|
bool UdpAccelInitServer(UDP_ACCEL *a, UCHAR *key, IP *detected_ip, IP *reported_ip, USHORT port);
|
||||||
void UdpAccelPoll(UDP_ACCEL *a);
|
void UdpAccelPoll(UDP_ACCEL *a);
|
||||||
void UdpAccelSetTick(UDP_ACCEL *a, UINT64 tick64);
|
void UdpAccelSetTick(UDP_ACCEL *a, UINT64 tick64);
|
||||||
BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip, UINT src_port);
|
BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip, UINT src_port);
|
||||||
@ -127,5 +131,3 @@ UINT UdpAccelCalcMss(UDP_ACCEL *a);
|
|||||||
void NatT_GetIpThread(THREAD *thread, void *param);
|
void NatT_GetIpThread(THREAD *thread, void *param);
|
||||||
|
|
||||||
#endif // UDPACCEL_H
|
#endif // UDPACCEL_H
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user