1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-11-22 17:39:53 +03:00

Fixing most errors, the link on Windows is working and is stable

This commit is contained in:
Evengard 2020-05-12 03:30:59 +03:00
parent a2a6502ab9
commit 2cfe031398
6 changed files with 384 additions and 247 deletions

View File

@ -1428,7 +1428,7 @@ void IPCProcessL3EventsEx(IPC *ipc, UINT64 now)
}
}
FreePacket(pkt);
FreePacketWithData(pkt);
}
IPCAssociateOnArpTable(ipc, &ip_src, src_mac);
@ -1438,6 +1438,10 @@ void IPCProcessL3EventsEx(IPC *ipc, UINT64 now)
// Place in the reception queue
InsertQueue(ipc->IPv4ReceivedQueue, NewBlock(data, size, 0));
}
else
{
Free(data); // We need to free the packet if we don't save it
}
}
else
@ -1470,9 +1474,9 @@ void IPCProcessL3EventsEx(IPC *ipc, UINT64 now)
{
case ICMPV6_TYPE_ROUTER_ADVERTISEMENT:
// We save the router advertisement data for later use
IPCIPv6AddRouterPrefix(ipc, &p->ICMPv6HeaderPacketInfo.OptionList, src_mac, &ip_src);
IPCIPv6AddRouterPrefixes(ipc, &p->ICMPv6HeaderPacketInfo.OptionList, src_mac, &ip_src);
IPCIPv6AssociateOnNDTEx(ipc, &ip_src, src_mac, true);
IPCIPv6AssociateOnNDTEx(ipc, &ip_src, &p->ICMPv6HeaderPacketInfo.OptionList.SourceLinkLayer->Address, true);
IPCIPv6AssociateOnNDTEx(ipc, &ip_src, p->ICMPv6HeaderPacketInfo.OptionList.SourceLinkLayer->Address, true);
break;
case ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT:
// We save the neighbor advertisements into NDT
@ -1495,6 +1499,10 @@ void IPCProcessL3EventsEx(IPC *ipc, UINT64 now)
{
InsertQueue(ipc->IPv6ReceivedQueue, NewBlock(data, size, 0));
}
else
{
Free(data); // We need to free the packet if we don't save it
}
FreePacket(p);
}
@ -2192,14 +2200,18 @@ bool IPCIPv6CheckExistingLinkLocal(IPC *ipc, UINT64 eui)
}
// RA
void IPCIPv6AddRouterPrefix(IPC *ipc, ICMPV6_OPTION_LIST *recvPrefix, UCHAR *macAddress, IP *ip)
void IPCIPv6AddRouterPrefixes(IPC *ipc, ICMPV6_OPTION_LIST *recvPrefix, UCHAR *macAddress, IP *ip)
{
UINT i, j;
for (i = 0; i < ICMPV6_OPTION_PREFIXES_MAX_COUNT; i++)
{
if (recvPrefix->Prefix[i] != NULL)
{
UINT i;
bool foundPrefix = false;
for (i = 0; i < LIST_NUM(ipc->IPv6RouterAdvs); i++)
for (j = 0; j < LIST_NUM(ipc->IPv6RouterAdvs); j++)
{
IPC_IPV6_ROUTER_ADVERTISEMENT *existingRA = LIST_DATA(ipc->IPv6RouterAdvs, i);
if (Cmp(&recvPrefix->Prefix->Prefix, &existingRA->RoutedPrefix.ipv6_addr, sizeof(IPV6_ADDR)) == 0)
IPC_IPV6_ROUTER_ADVERTISEMENT *existingRA = LIST_DATA(ipc->IPv6RouterAdvs, j);
if (Cmp(&recvPrefix->Prefix[i]->Prefix, &existingRA->RoutedPrefix.ipv6_addr, sizeof(IPV6_ADDR)) == 0)
{
foundPrefix = true;
break;
@ -2209,14 +2221,20 @@ void IPCIPv6AddRouterPrefix(IPC *ipc, ICMPV6_OPTION_LIST *recvPrefix, UCHAR *mac
if (!foundPrefix)
{
IPC_IPV6_ROUTER_ADVERTISEMENT *newRA = Malloc(sizeof(IPC_IPV6_ROUTER_ADVERTISEMENT));
IPv6AddrToIP(&newRA->RoutedPrefix, &recvPrefix->Prefix->Prefix);
IntToSubnetMask6(&newRA->RoutedMask, recvPrefix->Prefix->SubnetLength);
IPv6AddrToIP(&newRA->RoutedPrefix, &recvPrefix->Prefix[i]->Prefix);
IntToSubnetMask6(&newRA->RoutedMask, recvPrefix->Prefix[i]->SubnetLength);
CopyIP(&newRA->RouterAddress, ip);
Copy(newRA->RouterMacAddress, macAddress, 6);
Copy(newRA->RouterLinkLayerAddress, recvPrefix->SourceLinkLayer->Address, 6);
Add(ipc->IPv6RouterAdvs, newRA);
}
}
else
{
break;
}
}
}
bool IPCIPv6CheckUnicastFromRouterPrefix(IPC *ipc, IP *ip, IPC_IPV6_ROUTER_ADVERTISEMENT *matchedRA)
{
@ -2287,11 +2305,16 @@ UINT64 IPCIPv6GetServerEui(IPC *ipc)
packet = BuildICMPv6RouterSoliciation(&senderV6, &destV6, ipc->MacAddress, 0);
UINT64 giveup_time = Tick64() + (UINT64)(IPC_IPV6_RA_MAX_RETRIES * IPC_IPV6_RA_INTERVAL);
UINT64 timeout_retry = 0;
while (LIST_NUM(ipc->IPv6RouterAdvs) == 0)
{
UINT64 timeout_retry = Tick64() + (UINT64)IPC_IPV6_RA_INTERVAL;
UINT64 now = Tick64();
if (now >= timeout_retry)
{
timeout_retry = now + (UINT64)IPC_IPV6_RA_INTERVAL;
IPCIPv6SendWithDestMacAddr(ipc, packet->Buf, packet->Size, destMacAddress);
}
AddInterrupt(ipc->Interrupt, timeout_retry);
@ -2304,6 +2327,8 @@ UINT64 IPCIPv6GetServerEui(IPC *ipc)
// The processing should populate the received RAs by itself
IPCProcessL3Events(ipc);
}
FreeBuf(packet);
}
// Populating the IPv6 Server EUI for IPV6CP
@ -2379,6 +2404,10 @@ void IPCIPv6Send(IPC *ipc, void *data, UINT size)
void IPCIPv6SendWithDestMacAddr(IPC *ipc, void *data, UINT size, UCHAR *dest_mac_addr)
{
UCHAR tmp[1514];
IPV6_HEADER *header = data;
// Validate arguments
if (ipc == NULL || data == NULL || size < 40 || size > 1500 || dest_mac_addr == NULL)
{
@ -2397,6 +2426,60 @@ void IPCIPv6SendWithDestMacAddr(IPC *ipc, void *data, UINT size, UCHAR *dest_mac
// Data
Copy(tmp + 14, data, size);
// Parse the packet for ND ICMPv6 fixup
if (header->NextHeader == IP_PROTO_ICMPV6)
{
PKT *p = ParsePacketUpToICMPv6(tmp, size + 14);
if (p != NULL)
{
ICMPV6_OPTION_LINK_LAYER linkLayer;
BUF *buf;
BUF *optBuf;
BUF *packet;
// We need to rebuild the packet to
switch (p->ICMPv6HeaderPacketInfo.Type)
{
case ICMPV6_TYPE_NEIGHBOR_SOLICIATION:
if (p->ICMPv6HeaderPacketInfo.OptionList.SourceLinkLayer == NULL)
{
p->ICMPv6HeaderPacketInfo.OptionList.SourceLinkLayer = &linkLayer;
}
Copy(p->ICMPv6HeaderPacketInfo.OptionList.SourceLinkLayer->Address, ipc->MacAddress, 6);
case ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT:
if (p->ICMPv6HeaderPacketInfo.OptionList.TargetLinkLayer == NULL)
{
p->ICMPv6HeaderPacketInfo.OptionList.TargetLinkLayer = &linkLayer;
}
Copy(p->ICMPv6HeaderPacketInfo.OptionList.TargetLinkLayer->Address, ipc->MacAddress, 6);
}
switch (p->ICMPv6HeaderPacketInfo.Type)
{
case ICMPV6_TYPE_NEIGHBOR_SOLICIATION:
case ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT:
optBuf = BuildICMPv6Options(&p->ICMPv6HeaderPacketInfo.OptionList);
buf = NewBuf();
WriteBuf(buf, p->ICMPv6HeaderPacketInfo.Headers.HeaderPointer,
p->ICMPv6HeaderPacketInfo.Type == ICMPV6_TYPE_NEIGHBOR_SOLICIATION ? sizeof(ICMPV6_NEIGHBOR_SOLICIATION_HEADER) : sizeof(ICMPV6_NEIGHBOR_ADVERTISEMENT_HEADER));
WriteBufBuf(buf, optBuf);
packet = BuildICMPv6(&p->IPv6HeaderPacketInfo.IPv6Header->SrcAddress,
&p->IPv6HeaderPacketInfo.IPv6Header->DestAddress,
p->IPv6HeaderPacketInfo.IPv6Header->HopLimit,
p->ICMPv6HeaderPacketInfo.Type,
p->ICMPv6HeaderPacketInfo.Code,
buf->Buf,
buf->Size,
0);
Copy(tmp + 14, packet->Buf, packet->Size);
size = packet->Size;
FreeBuf(optBuf);
FreeBuf(buf);
FreeBuf(packet);
break;
}
}
FreePacket(p);
}
// Send
IPCSendL2(ipc, tmp, size + 14);
}
@ -2484,13 +2567,24 @@ void IPCIPv6SendUnicast(IPC *ipc, void *data, UINT size, IP *next_ip)
{
// We need to send the Neighbor Solicitation and save the packet for sending later
// Generate the MAC address from the multicast address
BUF *neighborSolicit;
UCHAR destMacAddress[6];
BUF *neighborSolicit = BuildICMPv6NeighborSoliciation(&header->SrcAddress, &header->DestAddress, ipc->MacAddress, 0);
IPV6_ADDR solicitAddress;
Zero(&solicitAddress, sizeof(IPV6_ADDR));
Copy(&solicitAddress.Value[13], &header->DestAddress.Value[13], 3);
solicitAddress.Value[0] = 0xFF;
solicitAddress.Value[1] = 0x02;
solicitAddress.Value[11] = 0x01;
solicitAddress.Value[12] = 0xFF;
neighborSolicit = BuildICMPv6NeighborSoliciation(&header->SrcAddress, &solicitAddress, ipc->MacAddress, 0);
destMacAddress[0] = 0x33;
destMacAddress[1] = 0x33;
Copy(&destMacAddress[2], &next_ip->ipv6_addr[12], sizeof(UINT));
Copy(&destMacAddress[2], &solicitAddress.Value[12], sizeof(UINT));
IPCIPv6SendWithDestMacAddr(ipc, neighborSolicit->Buf, neighborSolicit->Size, destMacAddress);
FreeBuf(neighborSolicit);
CHAR tmp[MAX_SIZE];
UCHAR *copy = Clone(data, size);
BLOCK *blk = NewBlock(copy, size, 0);

View File

@ -227,7 +227,7 @@ void IPCIPv6FlushNDT(IPC *ipc);
void IPCIPv6FlushNDTEx(IPC *ipc, UINT64 now);
bool IPCIPv6CheckExistingLinkLocal(IPC *ipc, UINT64 eui);
// RA
void IPCIPv6AddRouterPrefix(IPC *ipc, ICMPV6_OPTION_LIST *recvPrefix, UCHAR *macAddress, IP *ip);
void IPCIPv6AddRouterPrefixes(IPC *ipc, ICMPV6_OPTION_LIST *recvPrefix, UCHAR *macAddress, IP *ip);
bool IPCIPv6CheckUnicastFromRouterPrefix(IPC *ipc, IP *ip, IPC_IPV6_ROUTER_ADVERTISEMENT *matchedRA);
UINT64 IPCIPv6GetServerEui(IPC *ipc);
// Data flow

View File

@ -1284,6 +1284,7 @@ char *PacketLogParseProc(RECORD *rec)
TOKEN_LIST *t;
char tmp[MAX_SIZE];
bool tcp_conn;
UINT i;
// Validate arguments
if (rec == NULL)
{
@ -1686,14 +1687,21 @@ char *PacketLogParseProc(RECORD *rec)
snprintf(tmp, sizeof(tmp), "TargetLinkLayer=%s ", tmp2);
StrCat(info, sizeof(info), tmp);
}
if (ol->Prefix != NULL)
for (i = 0; i < ICMPV6_OPTION_PREFIXES_MAX_COUNT; i++)
{
if (ol->Prefix[i] != NULL)
{
char tmp2[MAX_SIZE];
IP6AddrToStr(tmp2, sizeof(tmp2), &ol->Prefix->Prefix);
IP6AddrToStr(tmp2, sizeof(tmp2), &ol->Prefix[i]->Prefix);
snprintf(tmp, sizeof(tmp), "Prefix=%s/%u PrefixFlag=0x%02X ", tmp2,
ol->Prefix->SubnetLength, ol->Prefix->Flags);
ol->Prefix[i]->SubnetLength, ol->Prefix[i]->Flags);
StrCat(info, sizeof(info), tmp);
}
else
{
break;
}
}
if (ol->Mtu != NULL)
{
snprintf(tmp, sizeof(tmp), "Mtu=%u ", Endian32(ol->Mtu->Mtu));

View File

@ -365,7 +365,7 @@ void PPPThread(THREAD *thread, void *param)
PPPSendPacketEx(p, pp, true);
FreePPPPacketEx(pp, true);
Free(b);
Free(b); // Not FreeBlock because freed in FreePPPPacketEx
}
}
else
@ -396,7 +396,7 @@ void PPPThread(THREAD *thread, void *param)
PPPSendPacketEx(p, pp, true);
FreePPPPacketEx(pp, true);
Free(b);
Free(b); // Not FreeBlock because freed in FreePPPPacketEx
}
}
else
@ -1961,7 +1961,7 @@ bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
{
UINT64 newValue = 0;
UINT64 value = READ_UINT64(t->Data);
if (!IPCIPv6CheckExistingLinkLocal(p->Ipc, value))
if (value != 0 && !IPCIPv6CheckExistingLinkLocal(p->Ipc, value))
{
t->IsAccepted = true;
p->Ipc->IPv6ClientEUI = value;

View File

@ -1140,6 +1140,7 @@ void BuildICMPv6OptionValue(BUF *b, UCHAR type, void *header_pointer, UINT total
BUF *BuildICMPv6Options(ICMPV6_OPTION_LIST *o)
{
BUF *b;
UINT i;
// Validate arguments
if (o == NULL)
{
@ -1156,9 +1157,16 @@ BUF *BuildICMPv6Options(ICMPV6_OPTION_LIST *o)
{
BuildICMPv6OptionValue(b, ICMPV6_OPTION_TYPE_TARGET_LINK_LAYER, o->TargetLinkLayer, sizeof(ICMPV6_OPTION_LINK_LAYER));
}
if (o->Prefix != NULL)
for (i = 0; i < ICMPV6_OPTION_PREFIXES_MAX_COUNT; i++)
{
BuildICMPv6OptionValue(b, ICMPV6_OPTION_TYPE_PREFIX, o->Prefix, sizeof(ICMPV6_OPTION_PREFIX));
if (o->Prefix[i] != NULL)
{
BuildICMPv6OptionValue(b, ICMPV6_OPTION_TYPE_PREFIX, o->Prefix[i], sizeof(ICMPV6_OPTION_PREFIX));
}
else
{
break;
}
}
if (o->Mtu != NULL)
{
@ -2402,7 +2410,15 @@ bool ParseICMPv6Options(ICMPV6_OPTION_LIST *o, UCHAR *buf, UINT size)
// Prefix Information
if (header_total_size >= sizeof(ICMPV6_OPTION_PREFIX))
{
o->Prefix = (ICMPV6_OPTION_PREFIX *)header_pointer;
UINT i;
for (i = 0; i < ICMPV6_OPTION_PREFIXES_MAX_COUNT; i++)
{
if (o->Prefix[i] == NULL)
{
o->Prefix[i] = (ICMPV6_OPTION_PREFIX *)header_pointer;
break;
}
}
}
else
{
@ -2556,6 +2572,7 @@ bool ParseICMPv6(PKT *p, UCHAR *buf, UINT size)
// Release of the ICMPv6 options
void FreeCloneICMPv6Options(ICMPV6_OPTION_LIST *o)
{
UINT i;
// Validate arguments
if (o == NULL)
{
@ -2564,13 +2581,19 @@ void FreeCloneICMPv6Options(ICMPV6_OPTION_LIST *o)
Free(o->SourceLinkLayer);
Free(o->TargetLinkLayer);
Free(o->Prefix);
for (i = 0; i < ICMPV6_OPTION_PREFIXES_MAX_COUNT; i++)
{
Free(o->Prefix[i]);
o->Prefix[i] = NULL;
}
Free(o->Mtu);
}
// Clone of the ICMPv6 options
void CloneICMPv6Options(ICMPV6_OPTION_LIST *dst, ICMPV6_OPTION_LIST *src)
{
UINT i;
// Validate arguments
if (dst == NULL || src == NULL)
{
@ -2581,7 +2604,17 @@ void CloneICMPv6Options(ICMPV6_OPTION_LIST *dst, ICMPV6_OPTION_LIST *src)
dst->SourceLinkLayer = Clone(src->SourceLinkLayer, sizeof(ICMPV6_OPTION_LINK_LAYER));
dst->TargetLinkLayer = Clone(src->TargetLinkLayer, sizeof(ICMPV6_OPTION_LINK_LAYER));
dst->Prefix = Clone(src->Prefix, sizeof(ICMPV6_OPTION_PREFIX));
for (i = 0; i < ICMPV6_OPTION_PREFIXES_MAX_COUNT; i++)
{
if (src->Prefix[i] != NULL)
{
dst->Prefix[i] = Clone(src->Prefix[i], sizeof(ICMPV6_OPTION_PREFIX));
}
else
{
break;
}
}
dst->Mtu = Clone(src->Mtu, sizeof(ICMPV6_OPTION_MTU));
}

View File

@ -399,12 +399,14 @@ struct ICMPV6_NEIGHBOR_ADVERTISEMENT_HEADER
#define ICMPV6_NEIGHBOR_ADVERTISEMENT_FLAG_SOLICITED 0x40 // Solicited flag
#define ICMPV6_NEIGHBOR_ADVERTISEMENT_FLAG_OVERWRITE 0x20 // Overwrite flag
#define ICMPV6_OPTION_PREFIXES_MAX_COUNT 10
// ICMPv6 option list
struct ICMPV6_OPTION_LIST
{
ICMPV6_OPTION_LINK_LAYER *SourceLinkLayer; // Source link-layer address
ICMPV6_OPTION_LINK_LAYER *TargetLinkLayer; // Target link-layer address
ICMPV6_OPTION_PREFIX *Prefix; // Prefix Information
ICMPV6_OPTION_PREFIX *Prefix[ICMPV6_OPTION_PREFIXES_MAX_COUNT]; // Prefix Information - may be multiple in one request
ICMPV6_OPTION_MTU *Mtu; // MTU
} GCC_PACKED;