Skip to content
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

Add IPv6 support to HTTP daemon #1074

Merged
merged 2 commits into from
May 29, 2024
Merged

Add IPv6 support to HTTP daemon #1074

merged 2 commits into from
May 29, 2024

Conversation

aryanA101a
Copy link
Contributor

@aryanA101a aryanA101a commented Apr 20, 2024

resolves #1065

Summary of changes:

  • Updated the APIs for retrieving network interfaces on posix-compliant systems and Windows to enable ipv6 support
  • Added dual stack flag from libmicrohttp to support both ipv4 and ipv6 clients

Compatibility notes
iphlpapi.h-getadaptersaddresses() : Minimum supported client Windows XP

Tested on
Ubuntu 22.04.4 LTS

src/server/internalServer.cpp Outdated Show resolved Hide resolved
Comment on lines 111 to 139
if (dwRetVal == NO_ERROR) {
PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
unsigned int i = 0;
for (PIP_ADAPTER_ADDRESSES temp = interfacesHead; temp != NULL;
temp = temp->Next) {
pUnicast = temp->FirstUnicastAddress;
if (pUnicast != NULL) {
for (i = 0; pUnicast != NULL; i++){
if (pUnicast->Address.lpSockaddr->sa_family == AF_INET)
{
sockaddr_in *si = (sockaddr_in *)(pUnicast->Address.lpSockaddr);
char host[INET_ADDRSTRLEN]={0};
inet_ntop(AF_INET, &(si->sin_addr), host, sizeof(host));
interfaces[temp->AdapterName].addr=host;
}
else if (pUnicast->Address.lpSockaddr->sa_family == AF_INET6)
{
sockaddr_in6 *si = (sockaddr_in6 *)(pUnicast->Address.lpSockaddr);
char host[INET6_ADDRSTRLEN]={0};
inet_ntop(AF_INET6, &(si->sin6_addr), host, sizeof(host));
if (!IN6_IS_ADDR_LINKLOCAL(&(si->sin6_addr)))
interfaces[temp->AdapterName].addr6=host;
}
pUnicast = pUnicast->Next;
}
}
}
} else {
std::cerr << "Call to GetAdaptersAddresses failed with error: "<< dwRetVal << std::endl;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix indentation (replace tabs with spaces)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are no tabs.

src/tools/networkTools.cpp Outdated Show resolved Hide resolved
if (0 != INADDR_ANY) {
sockAddr6.sin6_addr = in6addr_any;
}
m_addr = (kiwix::getBestPublicIp(m_ipv6)).addr6;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, it looks like this is why we may need the ipv6 boolean parameter. But are there realistic situations where the user trusts the application to select the IP address on its own but enforces the type of the IP address?

Copy link
Contributor Author

@aryanA101a aryanA101a Apr 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None that I can think of.

src/server/internalServer.cpp Outdated Show resolved Hide resolved
@aryanA101a
Copy link
Contributor Author

With the latest refactoring, any type of ip can be used with -i flag without the necessity of specifying -6 flag.

Copy link
Collaborator

@veloman-yunkan veloman-yunkan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am writing this summary after having added the review comments and having deleted/edited some of them (as I felt that my feedback starts being inconsistent). I read the discussion at kiwix/kiwix-tools#545 a little too late. My feeling is that the option --ipv6 is not a good way to instruct the kiwix server to support IPv6. Is it supposed to enforce IPv6 or merely enables it?

An alternative may be to use special values for the -i/--address options. For example,

  • all - listen on all available IP addresses (IPv4 and IPv6)
  • ipv4 - listen on all available IPv4 addresses
  • ipv6 - listen on all available IPv6 addresses
  • auto
  • network interface name (e.g. eth0, wlan0) - will be resolved to the IP address of the named interface

I think that we have to close in on the use model of this enhancement before proceeding with the PR.

include/tools.h Outdated Show resolved Hide resolved
include/server.h Outdated
@@ -65,6 +65,7 @@ namespace kiwix
void setIPv6(bool ipv6) { m_ipv6 = ipv6; }
int getPort();
std::string getAddress();
bool isAddressIPv6();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make const (in general, shortcomings of existing code shouldn't be copied).

src/tools/networkTools.cpp Outdated Show resolved Hide resolved
include/tools.h Outdated Show resolved Hide resolved
include/server.h Outdated Show resolved Hide resolved
include/server.h Outdated
@@ -78,6 +80,7 @@ namespace kiwix
bool m_withTaskbar = true;
bool m_withLibraryButton = true;
bool m_blockExternalLinks = false;
bool m_ipv6 = false;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Get rid of this data member.

src/server/internalServer.h Outdated Show resolved Hide resolved
src/server/internalServer.h Outdated Show resolved Hide resolved
src/tools/networkTools.cpp Show resolved Hide resolved
@veloman-yunkan
Copy link
Collaborator

With the latest refactoring, any type of ip can be used with -i flag without the necessity of specifying -6 flag.

What happens if you specify an IPv4 address together with the -6 flag?

@aryanA101a
Copy link
Contributor Author

aryanA101a commented Apr 24, 2024

I am writing this summary after having added the review comments and having deleted/edited some of them (as I felt that my feedback starts being inconsistent). I read the discussion at kiwix/kiwix-tools#545 a little too late. My feeling is that the option --ipv6 is not a good way to instruct the kiwix server to support IPv6. Is it supposed to enforce IPv6 or merely enables it?

Current model:
-i lets you provide both types of ip addr
-6 just tries to enforce ipv6. In case no ip address is provided it makes sure best public ip is ipv6
In either case an explicit ipv6 address or -6 ipv6 enforce flag, dual stack flag is turned on from libmicrohttp to support connections from both ipv4 and ipv6 clients

An alternative may be to use special values for the -i/--address options. For example,

  • ipv4 - listen on all available IPv4 addresses
  • ipv6 - listen on all available IPv6 addresses
  • all - listen on all available IP addresses (IPv4 and IPv6)
  • auto

Seems a good approach.

  • network interface name (e.g. eth0, wlan0) - will be resolved to the IP address of the named interface

I don't think a normal person will care about the specific network interfaces, so adding this much sugar seems redundant.
I think that ipv6 support is more about ensuring compatibility with ipv6 clients, although it does let us serve on ipv6 addresses, but that's not the sauce.

I think that we have to close in on the use model of this enhancement before proceeding with the PR.

      -f, -family <FAMILY>
              Specifies  the  protocol family to use. The protocol family identifier can be one of inet, inet6, bridge, mpls
              or link.  If this option is not present, the protocol family is guessed from other arguments. If the  rest  of
              the  command line does not give enough information to guess the family, ip falls back to the default one, usu‐
              ally inet or any.  link is a special family identifier meaning that no networking protocol is involved.

       -4     shortcut for -family inet.

       -6     shortcut for -family inet6.

from the man page of ip command

I'd still argue that the -6 flag is a concise way to enforce IPv6, though your suggestion seems like a good approach as well.

@veloman-yunkan @kelson42 What do you think?

@aryanA101a
Copy link
Contributor Author

With the latest refactoring, any type of ip can be used with -i flag without the necessity of specifying -6 flag.

What happens if you specify an IPv4 address together with the -6 flag?

@aryanA101a ➜ /workspaces/kiwix-tools (main) $ kiwix-serve wikipedia_en_100_mini_2023-08.zim -p 2002 -6 -i 127.0.0.1
Ip address 127.0.0.1  is not a valid ipv6 address

@kelson42
Copy link
Collaborator

kelson42 commented May 4, 2024

An alternative may be to use special values for the -i/--address options. For example,

  • ipv4 - listen on all available IPv4 addresses
  • ipv6 - listen on all available IPv6 addresses
  • all - listen on all available IP addresses (IPv4 and IPv6)
  • auto

Seems a good approach.

@aryanA101a Thank you for your patience. I have discussed the case with @veloman-yunkan and we agreed that this proposal was appropriate and leads to the removal of -4 and/or -6. I also don't see what is the value of auto!? Would you be able to change the interface that way?

@aryanA101a
Copy link
Contributor Author

Sure

@kelson42
Copy link
Collaborator

@aryanA101a Is that ready for a new review?

@aryanA101a
Copy link
Contributor Author

@mgautierfr I have modified the meson.build, but still win32-dyn build is failing.

@kelson42
Copy link
Collaborator

@aryanA101a @veloman-yunkan Not sure about the status here, ready to review?

Copy link
Collaborator

@veloman-yunkan veloman-yunkan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rebase the PR and beautify its history (in the worst case it should consist of a single commit, but I would appreciate if you can split it into a few meaningful incremental changes).

include/common.h Outdated
@@ -16,6 +16,7 @@

namespace kiwix {

enum IpMode { ipv4, ipv6, all };
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change to enum class (so that the members of this enumeration - and especially all - can be used only when qualified with the type name).

@kelson42
Copy link
Collaborator

@aryanA101a We are that far that we are almost ready to merge, any chance we can do that soon?

@kelson42
Copy link
Collaborator

@aryanA101a @veloman-yunkan I can not merge with what looks like legit CI errors.

@kelson42
Copy link
Collaborator

@aryanA101a If this PR requires a change at Kiwix Build, please create an issue explaining what is needed.

@aryanA101a
Copy link
Contributor Author

@aryanA101a If this PR requires a change at Kiwix Build, please create an issue explaining what is needed.

kiwix/kiwix-build#697

I'll need some input from @mgautierfr

meson.build Outdated
@@ -48,7 +48,10 @@ if host_machine.system() == 'windows' and static_deps
endif

if host_machine.system() == 'windows'
add_project_arguments('-DNOMINMAX', language: 'cpp')
add_project_arguments('-DNOMINMAX', language: 'cpp')
extra_link_args = ['-lshlwapi', '-lwinmm', '-lWs2_32', '-liphlpapi']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra_link_args is use as link arguments when compiling tests.
When compiling the library itself (and setting pkg_config link flags which will be used by projects linking with libzim), we use extra_libs.
That's why CI is still failing for Windows.

BTW, we should probably use only one variable extra_libs to avoid this kind of mistake. When fixing the pr, please also switch to extra_libs only.

@kelson42
Copy link
Collaborator

@aryanA101a @veloman-yunkan Last commit seems to fix the compilation problem to create binary for Windows. But this commit in significant and we have to request new review

Copy link
Collaborator

@veloman-yunkan veloman-yunkan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To the best of my understanding the only change since the last review was in meson.build. Then my previous approval still holds.

However, regarding the commit structure of this PR, I think that all changes to the source code (*.cpp, *.h files) should belong to one commit. The fix for building under windows should be in a separate commit.

@veloman-yunkan
Copy link
Collaborator

veloman-yunkan commented May 29, 2024

@aryanA101a @veloman-yunkan Last commit seems to fix the compilation problem to create binary for Windows. But this commit in significant and we have to request new review

That's a false impression. The last commit (which combines two unrelated changes) was amended with a small change that finally fixed the windows build. In a more reviewer friendly flow a fixup commit should have been created.

@kelson42
Copy link
Collaborator

OK, then merging so we can finally move forward.

@kelson42 kelson42 merged commit a1ce3d1 into kiwix:main May 29, 2024
14 checks passed
@veloman-yunkan
Copy link
Collaborator

Note that this PR is a backward incompatible API change. Which means that the next release of libkiwix must be 14.0 (unless backward compatibility is added).

@mgautierfr BTW, why are the versions of openzim and kiwix projects defined in the kiwix-build repository instead of in every project in a standardized way?

@mgautierfr
Copy link
Member

BTW, why are the versions of openzim and kiwix projects defined in the kiwix-build repository instead of in every project in a standardized way?

It is defined in every project as a dependency constraint. See for example
https://github.com/kiwix/kiwix-tools/blob/main/meson.build#L21-L22
Or each project define it own version like in https://github.com/kiwix/libkiwix/blob/main/meson.build#L2

kiwix-build is defining what we are building in our CI/release (and it must fulfills the constraints define in every project). Other packagers are free to use different version (as long as constraints are respected)

@veloman-yunkan
Copy link
Collaborator

Indeed. I somehow failed to locate the version in meson.build. Sorry for the silly question.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add IPV6 support
4 participants