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 early FreeBSD, NetBSD, OpenBSD support #37

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

neilalexander
Copy link
Contributor

This adds support for OpenBSD (tested) and also possibly FreeBSD (untested, but builds without error).

With some very minor tweaks, this code could also potentially support NetBSD, DragonflyBSD and Solaris.

Copy link
Owner

@songgao songgao left a comment

Choose a reason for hiding this comment

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

Thanks for working on BSD support! It'd be exciting to have them. I don't think what's currently in the PR would work on its own though. Could you please further explain you setup?

params_bsd.go Outdated Show resolved Hide resolved
ipv4_test.go Outdated Show resolved Hide resolved
if.go Outdated Show resolved Hide resolved
syscalls_bsd.go Outdated
"os"
)

const bsdTUNSIFINFO = (0x80000000) | ((4 & 0x1fff) << 16) | uint32(byte('t'))<<8 | 91
Copy link
Owner

Choose a reason for hiding this comment

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

If this is from a BSD source, please kindly mention the original header name and quote some important definitions, so that it's easier to understand if somebody else needs to change this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will look to add appropriate comments for it.

MTU int16
Type uint8
Dummy uint8
}
Copy link
Owner

Choose a reason for hiding this comment

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

Do these fields need to be exported?

Copy link
Owner

Choose a reason for hiding this comment

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

Actually it seems lines above this are not used at all. I was imagining you needed to make some syscalls to setup the tun/tap device. In your use case, do you call external commands to set them up? I think if that's the preferred use case, you wouldn't need this package at all. You can just use os.OpenFile directly.

I see there the second commit removed a ioctl function. Did you attempt to implement it first and removed it? I think it'd be nice to have syscalls handled in Go!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I do appear to have left this definition in by accident, as this would be handled elsewhere in my code (with the help of FD() above).

I did attempt to implement an ioctl function although then realised that other platforms do not necessarily have this implemented either, hence removal.

Copy link
Owner

Choose a reason for hiding this comment

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

then realised that other platforms do not necessarily have this implemented either, hence removal.

I think all three platforms that this package has support for already handle syscalls properly. They might be structured in different ways because of different underlying designs of the OS APIs, but the goal is a user of the package doesn't need to make syscalls before or after creating the interface using this package.

I imagine the OpenBSD version could be similar to syscalls_darwin.go and syscalls_linux.go.

neilalexander added a commit to yggdrasil-network/water that referenced this pull request Mar 1, 2018
@neilalexander
Copy link
Contributor Author

I have addressed the change reviews, including reverting the ipv4_test.go import.

The only exception is the definition of FD(), which I have left as-is. This has allowed simple access to the descriptor for later ioctls, even through an Interface{}.

I'd appreciate your thoughts.

@Arceliar
Copy link

Arceliar commented Mar 4, 2018

@songgao @neilalexander It looks like we can use fd := iface.ReadWriteCloser.(*os.File).Fd(), so the interface changes aren't required and have been removed.

@neilalexander
Copy link
Contributor Author

@songgao Do you mind re-reviewing?

FD() was removed and we have since added support for selecting between multiple tap0901 adapters on Windows.

@neilalexander neilalexander changed the title OpenBSD (and possibly FreeBSD) support Add BSD support and ability to select specific tap0901 on Windows May 9, 2018
@neilalexander
Copy link
Contributor Author

Do you mind to re-review?

@songgao
Copy link
Owner

songgao commented Nov 17, 2018

Sorry for the lack of response. You seem to have removed all the BSD syscalls, and the BSD portion of this PR is now basically a wrapper around os.OpenFile, which doesn't provide much value. In other words, one could just use os.OpenFile directly instead of this package.

As I mentioned in a comment above, all of three other platform supports take care of those syscalls setup. Do you have OpenBSD code using this package running somewhere? I assume some syscall/iotl are required there. If so moving the system calls into this PR would be great!

Copy link
Owner

@songgao songgao left a comment

Choose a reason for hiding this comment

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

Some initial feedback on the Windows code here. Also, would you mind splitting it into a separate PR? It's different enough from the BSD code. Also please run golint on the code.

cc @lixin9311 for Windows code.

@@ -170,12 +170,33 @@ func getdeviceid(componentID string) (deviceid string, err error) {
key.Close()
continue
}
if len(interfaceName) > 0 {
key2 := `SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}\`+val+`\Connection`
Copy link
Owner

Choose a reason for hiding this comment

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

The SYSTEM...318} part is also used above. Could probably make it a const and reuse?

@@ -11,6 +11,10 @@ type PlatformSpecificParams struct {
// use the default ComponentId. The default ComponentId is set to tap0901,
// the one used by OpenVPN.
ComponentID string
// Of course, you may have multiple tap0901 adapters on the system, in which
// case we need a friendlier way to identify them. In that case we can use
// the friendly name of the network adapter as set in Control Panel.
Copy link
Owner

Choose a reason for hiding this comment

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

Please make this comment start with InterfaceName, and explain what this parameter is. Otherwise it won't pass linter.

@@ -27,6 +31,7 @@ type PlatformSpecificParams struct {
func defaultPlatformSpecificParams() PlatformSpecificParams {
return PlatformSpecificParams{
ComponentID: "tap0901",
InterfaceName: "",
Copy link
Owner

Choose a reason for hiding this comment

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

"" is the default value of string, so it's not necessary to set this here.

key2 := `SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}\`+val+`\Connection`
k2, err := registry.OpenKey(registry.LOCAL_MACHINE, key2, registry.READ)
if err != nil {
fmt.Println("Unable to open", key2)
Copy link
Owner

Choose a reason for hiding this comment

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

Remove this line? Same as the fmt.Println below. Reason is that code using this package likely has stdout for other stuff, and writing into it without a way to turn it off doesn't seem like a good idea.

@soffokl
Copy link
Contributor

soffokl commented Mar 7, 2019

@neilalexander @songgao Do you have plans to continue working on this PR?
I depend on using multiple tap0901 on Windows at that moment.
And it will be good to keep it in the main project instead of a fork.

I can continue working on it if you don't want to finish it in the scope of the PR.

@neilalexander
Copy link
Contributor Author

neilalexander commented Mar 7, 2019

Hi @soffokl, I don't have the time at the moment to refactor the PR to satisfy @songgao's comments. I'd like to get back to it soon. However our fork at yggdrasil-network/water supports named Windows interfaces for now.

@songgao
Copy link
Owner

songgao commented Mar 7, 2019

@soffokl That’d be fantastic. Thanks!

@neilalexander neilalexander changed the title Add BSD support and ability to select specific tap0901 on Windows Add early FreeBSD, NetBSD, OpenBSD support Jul 20, 2019
@neilalexander
Copy link
Contributor Author

I've updated this PR for now to bring it back in line with your master branch and to include the bare-bones needed for FreeBSD/NetBSD/OpenBSD support, which is just the ReadWriteCloser.

The syscalls are not here at the moment because I have not got them working in my own code so far for BSD, so I will submit a later PR to add those.

I would like to propose we merge this to make the library at half-way usable on these BSD platforms and then I can bring my own repository back into sync with yours (when #67 and #68 are also merged) for submitting future changes.

@songgao
Copy link
Owner

songgao commented Aug 6, 2019

Sorry for dropping the ball here! Will look soon

Copy link
Owner

@songgao songgao left a comment

Choose a reason for hiding this comment

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

Thanks Neil; Have you had more updates on the syscall part? I'd love to have at least a usable tun or tap device working before merging into master. Otherwise it feels a bit confusing.

package water

// PlatformSpecificParams defines parameters in Config that are specific to
// Linux. A zero-value of such type is valid, yielding an interface
Copy link
Owner

Choose a reason for hiding this comment

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

s/Linux/BSD

@aki237
Copy link

aki237 commented Aug 8, 2020

@songgao Seems like tun implementation is little different from other (FreeBSD, NetBSD or DFly) tun implementations.

Each packet read or written is prefixed with a tunnel header consisting of a 4-byte network byte order integer containing the address family.

From their manpage (3rd Paragraph of the description)

Should this package handle the packet header or is it upto the application to remove it?

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.

5 participants