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

Listen on the interface #379

Closed
avengermsoft opened this issue Feb 17, 2020 · 6 comments
Closed

Listen on the interface #379

avengermsoft opened this issue Feb 17, 2020 · 6 comments
Labels

Comments

@avengermsoft
Copy link

avengermsoft commented Feb 17, 2020

Do you plan to listen on the interface?

Sample: "ListenInterface br-lan". I now have 4 ips addresses on the interface br-lan:

4: br-lan:  mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether dc:a6:32:0c:53:b4 brd ff:ff:ff:ff:ff:ff
    inet 192.168.97.98/27 brd 192.168.97.127 scope global br-lan
       valid_lft forever preferred_lft forever
    inet6 2a05:3580:xxxx:xxxx:dea6:32ff:fe0c:53b4/64 scope global dynamic noprefixroute
       valid_lft 13644sec preferred_lft 8244sec
    inet6 2a05:3580:xxxx:xxxx::98/128 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::dea6:32ff:fe0c:53b4/64 scope link
       valid_lft forever preferred_lft forever
@anacrolix
Copy link
Owner

@avengermsoft how would you generally do this in other languages? I believe you want to use https://golang.org/pkg/net/#InterfaceByName, https://golang.org/pkg/net/#Interface.Addrs, and #365 for this.

@avengermsoft
Copy link
Author

avengermsoft commented Feb 19, 2020

C++ example

struct ifreq ifr;

memset(&ifr, 0, sizeof(ifr));
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "eth0");
if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) < 0) {
    ... error handling ...
}

@anacrolix
Copy link
Owner

@avengermsoft do you already have a method to listen on the interface in the way you desire in Go? If you do, and it isn't exposed by the ClientConfig, you'll be interested in #380.

@avengermsoft
Copy link
Author

I found the code, but I don’t understand how to adapt it.

func bindToIf(conn net.Conn, interfaceName string) {
    ptrVal := reflect.ValueOf(conn)
    val := reflect.Indirect(ptrVal)
    //next line will get you the net.netFD
    fdmember := val.FieldByName("fd")
    val1 := reflect.Indirect(fdmember)                                   
    netFdPtr := val1.FieldByName("sysfd")                                           
    fd := int(netFdPtr.Int())
    //fd now has the actual fd for the socket
    err := syscall.SetsockoptString(fd, syscall.SOL_SOCKET,
                syscall.SO_BINDTODEVICE, interfaceName)
    if err != nil {
        log.Fatal(err)
    }

@anacrolix
Copy link
Owner

You can create your own Listener, and add it with Client.AddListener. The specifics for binding to an interface are outside the scope of this repo. I wasn't able to find a complete example online, I expect that after the bind (setsockopt) above, you should be able to fit the net.Conn into a net.Listener. You should also be able to create a raw, unbound net.Conn to pass to the above function.

You could also just listen explicitly on all of the IPs of the interface you listed, and then add them all with Client.AddListener.

@anacrolix
Copy link
Owner

I believe this can be closed. Feel free to field more questions.

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

No branches or pull requests

2 participants