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

Pixiecore doesn't work on Windows due to missing x/net/ipv4 support #18

Open
techtonik opened this issue Oct 26, 2016 · 8 comments
Open

Comments

@techtonik
Copy link

Fails to run on Windows:

>pixiecore.exe api -d 127.0.0.1:1111
not supported by windows

Why it is not supported? I couldn't find the source of that error.

@danderson
Copy link
Owner

That error comes from the stdlib's syscall package. I haven't dug deeper yet, but go.universe.tf/netboot/dhcp4 is the package that does the most complex/unusual low-level socket operations (using golang.org/x/net/ipv4), so I suspect it's a codepath in x/net/ipv4 that's doing something not implemented on windows.

If that's the case, unfortunately there's not much I can do about it, the default codepath in dhcp4 is already as portable as I was able to make it, so it's x/net/ipv4 that would need extra windows support.

I'll dig more later today to see if I can identify a specific codepath.

@techtonik
Copy link
Author

@danderson how do you debug it? I tried delve, but it doesn't work on 32-bit Windows (https://github.com/derekparker/delve/issues/656).

@danderson
Copy link
Owner

I don't use windows at all, so I don't know what debugger options exist. My strategy would be to add fmt.Println statements in https://github.com/google/netboot/blob/master/pixiecore/pixiecore.go#L185 to trace the initialization. I suspect it's newDHCP that is returning the error, but I could be wrong.

Once you find the function call that's returning the error, you can continue drilling down from there into that function and see which call is failing.

My guess, just looking at the code, is that the error comes from this SetControlMessage call in the dhcp4 package: https://github.com/google/netboot/blob/master/dhcp4/conn.go#L169 . This uses x/net/ipv4 to get information about the network interface that received a packet (required for DHCP, because we have to broadcast responses on the correct interface). My guess is that x/net/ipv4 has a TODO for supporting interface info.

@danderson
Copy link
Owner

bingo: https://github.com/golang/net/blob/master/ipv4/control_windows.go#L10

Looks like socket control messages are not at all implemented in x/net/ipv4, so the dhcp4 package cannot initialize on windows. If you know how to support this functionality for windows, pull requests for x/net are very welcome.

@danderson danderson changed the title fails with 'not supported by windows' Pixiecore doesn't work on Windows due to missing x/net/ipv4 support Oct 26, 2016
@techtonik
Copy link
Author

Hmm.. I am trying to understand this. pixiecore listens on all interfaces, and when a packer is received, it is impossible to tell which interface it was? How come?

I found https://stackoverflow.com/questions/3062205/setting-the-source-ip-for-a-udp-socket?noredirect=1&lq=1 - is it talking about the same issue?

@danderson
Copy link
Owner

The problem pixiecore has is not the same as the stackoverflow question, it's related to how DHCP works.

With a normal client<->server communication, when you receive a packet, you have both the source (client) IP and the destination (server) IP, so you can easily tell where the client is located and how to respond.

But with DHCP, when the client sends the DHCPDISCOVER packet, it does not have an IP address yet. So, the packet has a source IP of 0.0.0.0 (none), and a destination of 255.255.255.255 (broadcast). And we have to broadcast the response to 255.255.255.255 as well.

With the basic socket APIs, when you receive such a packet, you have no information at all about where the client is (which network interface), you just know that it sent a broadcast packet and your machine was able to see it. So, you don't know where you should send the response.

The function call at https://github.com/google/netboot/blob/master/dhcp4/conn.go#L169 uses an extension of the socket API to ask for interface information. So, when we receive a packet using this API, we get the packet, but also the OS tells us exactly the interface the packet arrived on. Then, when we send the response, we use this extension again, and tell the OS "please send this packet on interface X".

This extension to the basic socket API is required to implement DHCP correctly, because it's a slightly weird protocol that has to talk to clients with no IP addresses. I'm sure Windows offers a similar API to get this information, but x/net/ipv4 has no windows experts, so the support is missing (golang/go#7175).

@techtonik
Copy link
Author

How the interface on which a message received is identified? Is it an IP address or MAC?

@techtonik
Copy link
Author

Need time to wrap my head around system specific socket interface flags. I wish there was some table with socket optons and features. I guess on Linux conn.go wraps IP_PKTINFO flag described at https://linux.die.net/man/7/ip which seems implemented on Windows - https://msdn.microsoft.com/en-us/library/windows/desktop/hh285668(v=vs.85).aspx

Maybe a more simple workaround is to just listen on all interfaces separately?

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

No branches or pull requests

2 participants