1.支持指定IP出口,参数为bind=x.x.x.x
2.支持多网卡服务器,入口网卡作为出口网卡。
This commit is contained in:
parent
2707a8f0a9
commit
737b77981a
23
chain.go
23
chain.go
@ -151,17 +151,24 @@ func (c *Chain) dialWithOptions(ctx context.Context, network, address string, op
|
||||
}
|
||||
|
||||
if route.IsEmpty() {
|
||||
d := &net.Dialer{
|
||||
Timeout: timeout,
|
||||
}
|
||||
switch network {
|
||||
case "tcp", "tcp4", "tcp6":
|
||||
d.LocalAddr = &net.TCPAddr{
|
||||
IP: options.BindAddr,
|
||||
}
|
||||
case "udp", "udp4", "udp6":
|
||||
if address == "" {
|
||||
return net.ListenUDP(network, nil)
|
||||
}
|
||||
d.LocalAddr = &net.UDPAddr{
|
||||
IP: options.BindAddr,
|
||||
}
|
||||
default:
|
||||
}
|
||||
d := &net.Dialer{
|
||||
Timeout: timeout,
|
||||
// LocalAddr: laddr, // TODO: optional local address
|
||||
}
|
||||
|
||||
return d.DialContext(ctx, network, ipAddr)
|
||||
}
|
||||
|
||||
@ -325,6 +332,7 @@ func (c *Chain) selectRouteFor(addr string) (route *Chain, err error) {
|
||||
// ChainOptions holds options for Chain.
|
||||
type ChainOptions struct {
|
||||
Retries int
|
||||
BindAddr net.IP //绑定地址
|
||||
Timeout time.Duration
|
||||
Hosts *Hosts
|
||||
Resolver Resolver
|
||||
@ -360,3 +368,10 @@ func ResolverChainOption(resolver Resolver) ChainOption {
|
||||
opts.Resolver = resolver
|
||||
}
|
||||
}
|
||||
|
||||
// BindChainOption specifies tcp bind address used by Chain.Dial.
|
||||
func BindChainOption(bindAddr net.IP) ChainOption {
|
||||
return func(opts *ChainOptions) {
|
||||
opts.BindAddr = bindAddr
|
||||
}
|
||||
}
|
||||
|
20
forward.go
20
forward.go
@ -128,9 +128,17 @@ func (h *tcpDirectForwardHandler) Handle(conn net.Conn) {
|
||||
}
|
||||
}
|
||||
|
||||
//指定出口IP地址,没有绑定出口IP地址才考虑以入口网卡作为出口
|
||||
var bindAddr net.IP;
|
||||
if h.options.Node.BindAddr == nil {
|
||||
bindAddr = conn.LocalAddr().(*net.TCPAddr).IP
|
||||
}else {
|
||||
bindAddr = h.options.Node.BindAddr
|
||||
}
|
||||
cc, err = h.options.Chain.Dial(node.Addr,
|
||||
RetryChainOption(h.options.Retries),
|
||||
TimeoutChainOption(h.options.Timeout),
|
||||
BindChainOption(bindAddr),
|
||||
)
|
||||
if err != nil {
|
||||
log.Logf("[tcp] %s -> %s : %s", conn.RemoteAddr(), conn.LocalAddr(), err)
|
||||
@ -197,7 +205,17 @@ func (h *udpDirectForwardHandler) Handle(conn net.Conn) {
|
||||
}
|
||||
}
|
||||
|
||||
cc, err := h.options.Chain.DialContext(context.Background(), "udp", node.Addr)
|
||||
//指定出口IP地址,没有绑定出口IP地址才考虑以入口网卡作为出口
|
||||
var bindAddr net.IP;
|
||||
if h.options.Node.BindAddr == nil {
|
||||
bindAddr = conn.LocalAddr().(*net.UDPAddr).IP
|
||||
}else {
|
||||
bindAddr = h.options.Node.BindAddr
|
||||
}
|
||||
cc, err := h.options.Chain.DialContext(context.Background(),
|
||||
"udp",
|
||||
node.Addr,
|
||||
BindChainOption(bindAddr),)
|
||||
if err != nil {
|
||||
node.MarkDead()
|
||||
log.Logf("[udp] %s - %s : %s", conn.RemoteAddr(), conn.LocalAddr(), err)
|
||||
|
8
http.go
8
http.go
@ -261,10 +261,18 @@ func (h *httpHandler) handleRequest(conn net.Conn, req *http.Request) {
|
||||
continue
|
||||
}
|
||||
|
||||
//指定出口IP地址,没有绑定出口IP地址才考虑以入口网卡作为出口
|
||||
var bindAddr net.IP;
|
||||
if h.options.Node.BindAddr == nil {
|
||||
bindAddr = conn.LocalAddr().(*net.TCPAddr).IP
|
||||
}else {
|
||||
bindAddr = h.options.Node.BindAddr
|
||||
}
|
||||
cc, err = route.Dial(host,
|
||||
TimeoutChainOption(h.options.Timeout),
|
||||
HostsChainOption(h.options.Hosts),
|
||||
ResolverChainOption(h.options.Resolver),
|
||||
BindChainOption(bindAddr),
|
||||
)
|
||||
if err == nil {
|
||||
break
|
||||
|
8
http2.go
8
http2.go
@ -424,10 +424,18 @@ func (h *http2Handler) roundTrip(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintf(&buf, "%s", host)
|
||||
log.Log("[route]", buf.String())
|
||||
|
||||
//指定出口IP地址,没有绑定出口IP地址才考虑以入口网卡作为出口
|
||||
var bindAddr net.IP;
|
||||
if h.options.Node.BindAddr == nil {
|
||||
bindAddr = net.ParseIP(laddr)
|
||||
}else {
|
||||
bindAddr = h.options.Node.BindAddr
|
||||
}
|
||||
cc, err = route.Dial(host,
|
||||
TimeoutChainOption(h.options.Timeout),
|
||||
HostsChainOption(h.options.Hosts),
|
||||
ResolverChainOption(h.options.Resolver),
|
||||
BindChainOption(bindAddr),
|
||||
)
|
||||
if err == nil {
|
||||
break
|
||||
|
6
node.go
6
node.go
@ -3,6 +3,7 @@ package gost
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -22,6 +23,8 @@ type Node struct {
|
||||
Host string
|
||||
Protocol string
|
||||
Transport string
|
||||
BindAddr net.IP // 绑定出口
|
||||
OutFromIn bool // 是否使用入口IP网卡作为出口网卡,只有当没有绑定出口时才有效
|
||||
Remote string // remote address, used by tcp/udp port forwarding
|
||||
url *url.URL // raw url
|
||||
User *url.Userinfo
|
||||
@ -54,12 +57,15 @@ func ParseNode(s string) (node Node, err error) {
|
||||
node = Node{
|
||||
Addr: u.Host,
|
||||
Host: u.Host,
|
||||
BindAddr: net.ParseIP(u.Query().Get("bind")),
|
||||
Remote: strings.Trim(u.EscapedPath(), "/"),
|
||||
Values: u.Query(),
|
||||
User: u.User,
|
||||
marker: &failMarker{},
|
||||
url: u,
|
||||
}
|
||||
outFromIn, _ := strconv.ParseBool(u.Query().Get("outFromIn"))
|
||||
node.OutFromIn = outFromIn
|
||||
|
||||
u.RawQuery = ""
|
||||
u.User = nil
|
||||
|
14
relay.go
14
relay.go
@ -221,10 +221,24 @@ func (h *relayHandler) Handle(conn net.Conn) {
|
||||
}
|
||||
|
||||
log.Logf("[relay] %s -> %s -> %s", conn.RemoteAddr(), conn.LocalAddr(), raddr)
|
||||
|
||||
//指定出口IP地址,没有绑定出口IP地址才考虑以入口网卡作为出口
|
||||
var bindAddr net.IP
|
||||
if h.options.Node.BindAddr == nil {
|
||||
switch addr := conn.LocalAddr().(type) {
|
||||
case *net.TCPAddr:
|
||||
bindAddr = addr.IP
|
||||
case *net.UDPAddr:
|
||||
bindAddr = addr.IP
|
||||
}
|
||||
}else {
|
||||
bindAddr = h.options.Node.BindAddr
|
||||
}
|
||||
cc, err = h.options.Chain.DialContext(ctx,
|
||||
network, raddr,
|
||||
RetryChainOption(h.options.Retries),
|
||||
TimeoutChainOption(h.options.Timeout),
|
||||
BindChainOption(bindAddr),
|
||||
)
|
||||
if err != nil {
|
||||
log.Logf("[relay] %s -> %s : %s", conn.RemoteAddr(), raddr, err)
|
||||
|
8
sni.go
8
sni.go
@ -151,10 +151,18 @@ func (h *sniHandler) Handle(conn net.Conn) {
|
||||
fmt.Fprintf(&buf, "%s", host)
|
||||
log.Log("[route]", buf.String())
|
||||
|
||||
//指定出口IP地址,没有绑定出口IP地址才考虑以入口网卡作为出口
|
||||
var bindAddr net.IP;
|
||||
if h.options.Node.BindAddr == nil {
|
||||
bindAddr = conn.LocalAddr().(*net.TCPAddr).IP
|
||||
}else {
|
||||
bindAddr = h.options.Node.BindAddr
|
||||
}
|
||||
cc, err = route.Dial(host,
|
||||
TimeoutChainOption(h.options.Timeout),
|
||||
HostsChainOption(h.options.Hosts),
|
||||
ResolverChainOption(h.options.Resolver),
|
||||
BindChainOption(bindAddr),
|
||||
)
|
||||
if err == nil {
|
||||
break
|
||||
|
24
socks.go
24
socks.go
@ -939,10 +939,24 @@ func (h *socks5Handler) handleConnect(conn net.Conn, req *gosocks5.Request) {
|
||||
fmt.Fprintf(&buf, "%s", host)
|
||||
log.Log("[route]", buf.String())
|
||||
|
||||
//指定出口IP地址,没有绑定出口IP地址才考虑以入口网卡作为出口
|
||||
var bindAddr net.IP;
|
||||
if h.options.Node.BindAddr == nil {
|
||||
switch addr := conn.LocalAddr().(type) {
|
||||
case *net.TCPAddr:
|
||||
bindAddr = addr.IP
|
||||
case *net.UDPAddr:
|
||||
bindAddr = addr.IP
|
||||
}
|
||||
}else {
|
||||
bindAddr = h.options.Node.BindAddr
|
||||
}
|
||||
|
||||
cc, err = route.Dial(host,
|
||||
TimeoutChainOption(h.options.Timeout),
|
||||
HostsChainOption(h.options.Hosts),
|
||||
ResolverChainOption(h.options.Resolver),
|
||||
BindChainOption(bindAddr),
|
||||
)
|
||||
if err == nil {
|
||||
break
|
||||
@ -1754,10 +1768,20 @@ func (h *socks4Handler) handleConnect(conn net.Conn, req *gosocks4.Request) {
|
||||
fmt.Fprintf(&buf, "%s", addr)
|
||||
log.Log("[route]", buf.String())
|
||||
|
||||
//指定出口IP地址,没有绑定出口IP地址才考虑以入口网卡作为出口
|
||||
//socks4 只支持tcp
|
||||
var bindAddr net.IP
|
||||
if h.options.Node.BindAddr == nil {
|
||||
bindAddr = conn.LocalAddr().(*net.TCPAddr).IP
|
||||
}else {
|
||||
bindAddr = h.options.Node.BindAddr
|
||||
}
|
||||
|
||||
cc, err = route.Dial(addr,
|
||||
TimeoutChainOption(h.options.Timeout),
|
||||
HostsChainOption(h.options.Hosts),
|
||||
ResolverChainOption(h.options.Resolver),
|
||||
BindChainOption(bindAddr),
|
||||
)
|
||||
if err == nil {
|
||||
break
|
||||
|
13
ss.go
13
ss.go
@ -181,10 +181,23 @@ func (h *shadowHandler) Handle(conn net.Conn) {
|
||||
fmt.Fprintf(&buf, "%s", host)
|
||||
log.Log("[route]", buf.String())
|
||||
|
||||
//指定出口IP地址,没有绑定出口IP地址才考虑以入口网卡作为出口
|
||||
var bindAddr net.IP;
|
||||
if h.options.Node.BindAddr == nil {
|
||||
switch addr := conn.LocalAddr().(type) {
|
||||
case *net.TCPAddr:
|
||||
bindAddr = addr.IP
|
||||
case *net.UDPAddr:
|
||||
bindAddr = addr.IP
|
||||
}
|
||||
}else {
|
||||
bindAddr = h.options.Node.BindAddr
|
||||
}
|
||||
cc, err = route.Dial(host,
|
||||
TimeoutChainOption(h.options.Timeout),
|
||||
HostsChainOption(h.options.Hosts),
|
||||
ResolverChainOption(h.options.Resolver),
|
||||
BindChainOption(bindAddr),
|
||||
)
|
||||
if err == nil {
|
||||
break
|
||||
|
Loading…
Reference in New Issue
Block a user