-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added IPv6 support for client #107
base: master
Are you sure you want to change the base?
Conversation
This DNS lookup prefer IPv6, and return an IPv4 as fallback. If the client doesnt have IPv6 compatibility, then the DNS probe gonna return IPv4 only
Re, the PR in link for IPv6 support, on the server side: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally great job, please see if you can address the comments I made.
Could you also explain to my what the rationale is behind adding so many comments and doing so many unrelated changes? I'm just curious.
src/Network/Core.cpp
Outdated
Terminate = true; | ||
return; | ||
|
||
const std::regex ipv4v6Pattern(R"(((^\h*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\h*(|/([0-9]|[1-2][0-9]|3[0-2]))$)|(^\h*((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\h*(|/([0-9]|[0-9][0-9]|1[0-1][0-9]|12[0-8]))$)))"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we not just let the connect() / bind() syscalls handle the validation check of ipv6's? :)
src/Network/Core.cpp
Outdated
@@ -87,6 +98,7 @@ void Parse(std::string Data, SOCKET CSocket) { | |||
Data = Code + HTTP::Get("https://backend.beammp.com/servers-info"); | |||
break; | |||
case 'C': | |||
//TODO StartSync Here |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please either do or remove the todo, or create an issue
src/Network/Core.cpp
Outdated
info("Game Connected!"); | ||
info("Game Connected to LUA interface!"); | ||
GameHandler(CSocket); | ||
warn("Game Reconnecting..."); | ||
warn("Game reconnecting to LUA interface..."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this was fine, why the change?
LSocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol); | ||
if (LSocket == -1) { | ||
debug("(Core) socket failed with error: " + std::to_string(WSAGetLastError())); | ||
freeaddrinfo(res); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason we don't need freeaddrinfo anymore?
src/Network/DNS.cpp
Outdated
//Loop all and return it by prefeence ipv6 | ||
for (struct addrinfo* ptr = addresses; ptr != nullptr; ptr = ptr->ai_next) { | ||
char ipstr[INET6_ADDRSTRLEN] = { 0 }; | ||
|
||
if (ptr->ai_family == AF_INET6) { | ||
struct sockaddr_in6* ipv6 = (struct sockaddr_in6*)ptr->ai_addr; | ||
inet_ntop(AF_INET6, &(ipv6->sin6_addr), ipstr, sizeof(ipstr)); | ||
resolved = ipstr; | ||
break; //Break if IPv6 finded | ||
} | ||
else if (ptr->ai_family == AF_INET) { | ||
struct sockaddr_in* ipv4 = (struct sockaddr_in*)ptr->ai_addr; | ||
inet_ntop(AF_INET, &(ipv4->sin_addr), ipstr, sizeof(ipstr)); | ||
resolved = ipstr; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usually you just loop over resolved addresses, attempt to connect, and take the first one that connects. Is there a good reason why we don't just do that here?
src/Network/VehicleData.cpp
Outdated
if (AF == AF_INET) { | ||
// IPv4 | ||
struct sockaddr_in serverAddrV4; | ||
memset(&serverAddrV4, 0, sizeof(sockaddr_in)); | ||
serverAddrV4.sin_family = AF_INET; | ||
serverAddrV4.sin_port = htons(Port); | ||
inet_pton(AF_INET, IP.c_str(), &serverAddrV4.sin_addr); | ||
memcpy(ToServer, &serverAddrV4, sizeof(sockaddr_in)); | ||
addrLen = sizeof(sockaddr_in); | ||
} else { | ||
// IPv6 | ||
struct sockaddr_in6 serverAddrV6; | ||
memset(&serverAddrV6, 0, sizeof(sockaddr_in6)); | ||
serverAddrV6.sin6_family = AF_INET6; | ||
serverAddrV6.sin6_port = htons(Port); | ||
inet_pton(AF_INET6, IP.c_str(), &serverAddrV6.sin6_addr); | ||
memcpy(ToServer, &serverAddrV6, sizeof(sockaddr_in6)); | ||
addrLen = sizeof(sockaddr_in6); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is almost duplicated down in VehicleEvent, could we pull this out into a function maybe?
I'have tested the behavior waited
Based on Windows's documentation, the entire app need at least one WSAStarup call, other gonna juste increment a counter, for wich the app need the same number of WSACleanup. https://learn.microsoft.com/fr-fr/windows/win32/api/winsock/nf-winsock-wsastartup To simplify, and to increase a lot the visibility, the app will call one WSAStartup, and one WSACleanup at all. This is done on CoreNetwork function.
Hello, I worked on the client side to fully support IPv6 (and still IPv4 of course)
And I changed some mechanisms that don't break everything:
The DNS resolver can now return IPv4 or IPv6, and prefer IPv6 (as OS like Windows do)
I think I have tested everything:
I have also added vcpkg, as beamng-server has, it is simpler for me to "clone and go" this project.
The server side has needed some modification, which I let you check it on the server repo! (ill add the PR link after)
I hope everything is good to go!