英文:
How to use VPN(pptp) with golang net package?
问题
我在服务器上绑定了几个 VPN,它们分别是 ppp0 ~ ppp4。
现在出现了一个问题。我想要启动5个进程,每个进程都使用不同的网络接口。
proc0 -> ppp0
proc1 -> ppp1
proc2 -> ppp2
proc3 -> ppp3
proc4 -> ppp4
我知道如何使用 C 语言来实现这个功能,只需要使用带有参数 SO_BINDTODEVICE 的 setsockopt 函数。
但是如何在 Golang 的 net 包中实现这个功能呢?
英文:
I've bound several vpn on the server which is ppp0 ~ ppp4.
Now comes the problem.I want to start 5 progresses each one use the difference network interface.<br />
proc0 -> ppp0<br />
proc1 -> ppp1<br />
proc2 -> ppp2<br />
proc3 -> ppp3<br />
proc4 -> ppp4<br />
I now how to do this with c language.Just use setsockopt with parameter SO_BINDTODEVICE.
But how to do this with net package in golang?
答案1
得分: 1
你可能想要使用net.Interfaces()
来获取表示系统上网络接口的net.Interface()
切片,或者,如果你知道接口的名称,可以使用net.InterfaceByName()
来获取特定的net.Interface
。
ppp0, err := net.InterfaceByName("ppp0")
然后,你可以调用返回的net.Interface
的Interface.Addrs()
方法来获取接口的IP地址。
addrs, err := ppp0.Addrs()
然后,你可以在你的代码中使用所需的地址(可能使用net.ListenIP
或net.DialIP
)。
addr, err := net.ResolveIPAddr("ip4", addrs[0])
// 检查错误
conn, err := net.ListenIP("ip4:pptp", addr)
// 检查错误,然后使用conn进行操作
关于同时为多个接口执行此操作,你可以为每个监听器/接口启动一个goroutine,并通过通道传输流量,但这取决于你想要做什么。(你只是记录数据、发送数据、修改数据等等)
英文:
You probably want net.Interfaces()
to get a slice of net.Interface()
representing the network interfaces on your system, or, as you know the interface names, you can use net.InterfaceByName()
to get a particular net.Interface
.
ppp0, err := net.InterfaceByName("ppp0")
You can then call Interface.Addrs()
on the returned net.Interface
and get the interface's IP address(es).
addrs, err := ppp0.Addrs()
You can then use the desired address in the rest of your code (probably using net.ListenIP
or net.DialIP
.
addr, err := net.ResolveIPAddr("ip4", addrs[0])
// check err
conn, err := net.ListenIP("ip4:pptp", addr)
// check err, then do stuff with conn
Regarding doing this for more than one interface concurrently, you can launch a goroutine for each listener / interface, and move the traffic over channels, but this really depends on what you want to do. (are you just logging the data, sending the data, modifying the data etc.)
答案2
得分: 0
拨号器的LocalAddr对于ppp接口不起作用,我们应该使用setsockopt
函数将SOL_SOCKET
标志设置为套接字,对于go 1.11+,你可以像这样创建一个拨号器:
dialer := net.Dialer{
Control: func(network, address string, c syscall.RawConn) error {
return c.Control(func(fd uintptr) {
err := syscall.SetsockoptString(int(fd), syscall.SOL_SOCKET, 25, "ppp0")
if err != nil {
log.Printf("control: %s", err)
return
}
})
},
}
// 使用拨号器
英文:
The dialer's LocalAddr doesn't work for ppp interfaces, we should set the SOL_SOCKET
flag to socket using setsockopt
, for go 1.11+ you can create a dialer like this
dialer := net.Dialer{
Control: func(network, address string, c syscall.RawConn) error {
return c.Control(func(fd uintptr) {
err := syscall.SetsockoptString(int(fd), syscall.SOL_SOCKET, 25, "ppp0")
if err != nil {
log.Printf("control: %s", err)
return
}
})
},
}
// use the dialer
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论