如何使用Golang的net包与VPN(PPTP)一起使用?

huangapple go评论79阅读模式
英文:

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.InterfaceInterface.Addrs()方法来获取接口的IP地址。

addrs, err := ppp0.Addrs()

然后,你可以在你的代码中使用所需的地址(可能使用net.ListenIPnet.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(&quot;ppp0&quot;)

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(&quot;ip4&quot;, addrs[0])
// check err
conn, err := net.ListenIP(&quot;ip4:pptp&quot;, 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, &quot;ppp0&quot;)
				if err != nil {
					log.Printf(&quot;control: %s&quot;, err)
					return
				}
			})
		},
	}
	// use the dialer

huangapple
  • 本文由 发表于 2015年1月22日 12:32:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/28081336.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定