1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-11-23 01:49:53 +03:00

Cedar/IPC: Improve IPv6CP configuration

This commit is contained in:
Yihong Wu 2023-01-28 09:05:28 +00:00
parent 0e8174c6cf
commit 0cdf0eacbf
3 changed files with 23 additions and 52 deletions

View File

@ -2128,7 +2128,7 @@ void IPCIPv6Init(IPC *ipc)
ipc->IPv6RouterAdvs = NewList(NULL); ipc->IPv6RouterAdvs = NewList(NULL);
ipc->IPv6ClientEUI = 0; ipc->IPv6ClientEUI = 0;
ipc->IPv6ServerEUI = 0; GenerateEui64Address6((UCHAR *)&ipc->IPv6ServerEUI, ipc->MacAddress);
ipc->IPv6State = IPC_PROTO_STATUS_CLOSED; ipc->IPv6State = IPC_PROTO_STATUS_CLOSED;
} }
@ -2364,6 +2364,12 @@ bool IPCIPv6CheckUnicastFromRouterPrefix(IPC *ipc, IP *ip, IPC_IPV6_ROUTER_ADVER
UINT i; UINT i;
IPC_IPV6_ROUTER_ADVERTISEMENT *matchingRA = NULL; IPC_IPV6_ROUTER_ADVERTISEMENT *matchingRA = NULL;
bool isInPrefix = false; bool isInPrefix = false;
if (LIST_NUM(ipc->IPv6RouterAdvs) == 0 && IPCSendIPv6RouterSoliciation(ipc) == false)
{
return false;
}
for (i = 0; i < LIST_NUM(ipc->IPv6RouterAdvs); i++) for (i = 0; i < LIST_NUM(ipc->IPv6RouterAdvs); i++)
{ {
IPC_IPV6_ROUTER_ADVERTISEMENT *ra = LIST_DATA(ipc->IPv6RouterAdvs, i); IPC_IPV6_ROUTER_ADVERTISEMENT *ra = LIST_DATA(ipc->IPv6RouterAdvs, i);
@ -2383,19 +2389,13 @@ bool IPCIPv6CheckUnicastFromRouterPrefix(IPC *ipc, IP *ip, IPC_IPV6_ROUTER_ADVER
return isInPrefix; return isInPrefix;
} }
// Send router solicitation and then eventually populate the info from Router Advertisements // Send router solicitation to find a router
UINT64 IPCIPv6GetServerEui(IPC *ipc) bool IPCSendIPv6RouterSoliciation(IPC *ipc)
{ {
// It is already configured, nothing to do here
if (ipc->IPv6ServerEUI != 0)
{
return ipc->IPv6ServerEUI;
}
// If we don't have a valid client EUI, we can't generate a correct link local // If we don't have a valid client EUI, we can't generate a correct link local
if (ipc->IPv6ClientEUI == 0) if (ipc->IPv6ClientEUI == 0)
{ {
return ipc->IPv6ServerEUI; return false;
} }
if (LIST_NUM(ipc->IPv6RouterAdvs) == 0) if (LIST_NUM(ipc->IPv6RouterAdvs) == 0)
@ -2440,7 +2440,8 @@ UINT64 IPCIPv6GetServerEui(IPC *ipc)
if (Tick64() >= giveup_time) if (Tick64() >= giveup_time)
{ {
// We failed to receive any router advertisements // We failed to receive any router advertisements
break; FreeBuf(packet);
return false;
} }
// The processing should populate the received RAs by itself // The processing should populate the received RAs by itself
@ -2450,24 +2451,7 @@ UINT64 IPCIPv6GetServerEui(IPC *ipc)
FreeBuf(packet); FreeBuf(packet);
} }
// Populating the IPv6 Server EUI for IPV6CP return true;
if (LIST_NUM(ipc->IPv6RouterAdvs) > 0)
{
IPC_IPV6_ROUTER_ADVERTISEMENT *ra = LIST_DATA(ipc->IPv6RouterAdvs, 0);
Copy(&ipc->IPv6ServerEUI, &ra->RouterAddress.address[8], sizeof(ipc->IPv6ServerEUI));
}
// If it is still not defined, let's just generate something random
while (ipc->IPv6ServerEUI == 0)
{
ipc->IPv6ServerEUI = Rand64();
if (ipc->IPv6ClientEUI == ipc->IPv6ServerEUI)
{
ipc->IPv6ServerEUI = 0;
}
}
return ipc->IPv6ServerEUI;
} }
// Data flow // Data flow

View File

@ -155,7 +155,7 @@ struct IPC
LIST *IPv6NeighborTable; // Neighbor Discovery Table LIST *IPv6NeighborTable; // Neighbor Discovery Table
LIST *IPv6RouterAdvs; // Router offered prefixes LIST *IPv6RouterAdvs; // Router offered prefixes
UINT64 IPv6ClientEUI; // The EUI of the client (for the SLAAC autoconf) UINT64 IPv6ClientEUI; // The EUI of the client (for the SLAAC autoconf)
UINT64 IPv6ServerEUI; // The EUI of the server (from the RA discovery) UINT64 IPv6ServerEUI; // The EUI of the server (from the IPC Mac address)
}; };
// MS-CHAPv2 authentication information // MS-CHAPv2 authentication information
@ -233,7 +233,7 @@ bool IPCIPv6CheckExistingLinkLocal(IPC *ipc, UINT64 eui);
// RA // RA
void IPCIPv6AddRouterPrefixes(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); bool IPCIPv6CheckUnicastFromRouterPrefix(IPC *ipc, IP *ip, IPC_IPV6_ROUTER_ADVERTISEMENT *matchedRA);
UINT64 IPCIPv6GetServerEui(IPC *ipc); bool IPCSendIPv6RouterSoliciation(IPC *ipc);
// Data flow // Data flow
BLOCK *IPCIPv6Recv(IPC *ipc); BLOCK *IPCIPv6Recv(IPC *ipc);
void IPCIPv6Send(IPC *ipc, void *data, UINT size); void IPCIPv6Send(IPC *ipc, void *data, UINT size);

View File

@ -2191,7 +2191,7 @@ bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
{ {
UINT64 newValue = 0; UINT64 newValue = 0;
UINT64 value = READ_UINT64(t->Data); UINT64 value = READ_UINT64(t->Data);
if (value != 0 && IPCIPv6CheckExistingLinkLocal(p->Ipc, value) == false) if (value != 0 && value != p->Ipc->IPv6ServerEUI && IPCIPv6CheckExistingLinkLocal(p->Ipc, value) == false)
{ {
t->IsAccepted = true; t->IsAccepted = true;
p->Ipc->IPv6ClientEUI = value; p->Ipc->IPv6ClientEUI = value;
@ -2199,23 +2199,14 @@ bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
else else
{ {
t->IsAccepted = false; t->IsAccepted = false;
GenerateEui64Address6((UCHAR *)&newValue, p->Ipc->MacAddress); while (true)
if (newValue != value && IPCIPv6CheckExistingLinkLocal(p->Ipc, newValue) == false)
{ {
WRITE_UINT64(t->AltData, newValue); newValue = Rand64();
t->AltDataSize = sizeof(UINT64); if (newValue != 0 && newValue != p->Ipc->IPv6ServerEUI && IPCIPv6CheckExistingLinkLocal(p->Ipc, newValue) == false)
}
else
{
while (true)
{ {
newValue = Rand64(); WRITE_UINT64(t->AltData, newValue);
if (IPCIPv6CheckExistingLinkLocal(p->Ipc, newValue) == false) t->AltDataSize = sizeof(UINT64);
{ break;
WRITE_UINT64(t->AltData, newValue);
t->AltDataSize = sizeof(UINT64);
break;
}
} }
} }
} }
@ -2242,11 +2233,7 @@ bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
if (p->Ipc->IPv6ClientEUI != 0 && IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) == IPC_PROTO_STATUS_CLOSED) if (p->Ipc->IPv6ClientEUI != 0 && IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) == IPC_PROTO_STATUS_CLOSED)
{ {
PPP_LCP *c = NewPPPLCP(PPP_LCP_CODE_REQ, 0); PPP_LCP *c = NewPPPLCP(PPP_LCP_CODE_REQ, 0);
UINT64 serverEui = IPCIPv6GetServerEui(p->Ipc); Add(c->OptionList, NewPPPOption(PPP_IPV6CP_OPTION_EUI, &p->Ipc->IPv6ServerEUI, sizeof(UINT64)));
if (serverEui != 0 && serverEui != p->Ipc->IPv6ClientEUI)
{
Add(c->OptionList, NewPPPOption(PPP_IPV6CP_OPTION_EUI, &serverEui, sizeof(UINT64)));
}
if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_IPV6CP, c) == false) if (PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_IPV6CP, c) == false)
{ {
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);