diff --git a/internal/config/pan_config.go b/internal/config/pan_config.go index 75f1695..cc144cd 100644 --- a/internal/config/pan_config.go +++ b/internal/config/pan_config.go @@ -198,10 +198,6 @@ func (c *PanConfig) init() error { if c.Proxy != "" { requester.SetGlobalProxy(c.Proxy) } - // 设置本地网卡地址 - if c.LocalAddrs != "" { - requester.SetLocalTCPAddrList(strings.Split(c.LocalAddrs, ",")...) - } // 设置域名解析策略 IPv4 or IPv6 t := requester.IPAny @@ -212,6 +208,15 @@ func (c *PanConfig) init() error { } requester.SetPreferIPType(t) + // 设置本地网卡地址 + if c.LocalAddrs != "" { + ips := ParseLocalAddress(c.LocalAddrs) + if len(ips) > 0 { + logger.Verboseln("bind local address list: ", ips) + requester.SetLocalTCPAddrList(ips...) + } + } + return nil } diff --git a/internal/config/pan_config_export.go b/internal/config/pan_config_export.go index 6dd73a2..68747ac 100644 --- a/internal/config/pan_config_export.go +++ b/internal/config/pan_config_export.go @@ -33,7 +33,10 @@ func (c *PanConfig) SetProxy(proxy string) { // SetLocalAddrs 设置localAddrs func (c *PanConfig) SetLocalAddrs(localAddrs string) { c.LocalAddrs = localAddrs - requester.SetLocalTCPAddrList(strings.Split(localAddrs, ",")...) + ips := ParseLocalAddress(localAddrs) + if len(ips) > 0 { + requester.SetLocalTCPAddrList(ips...) + } } func (c *PanConfig) SetPreferIPType(ipType string) { @@ -112,7 +115,7 @@ func (c *PanConfig) PrintTable() { []string{"max_upload_rate", showMaxRate(c.MaxUploadRate), "", "限制单个文件最大上传速度, 0代表不限制"}, []string{"savedir", c.SaveDir, "", "下载文件的储存目录"}, []string{"proxy", c.Proxy, "", "设置代理, 支持 http/socks5 代理,例如: http://127.0.0.1:8888 或者 socks5://127.0.0.1:8889"}, - []string{"local_addrs", c.LocalAddrs, "", "设置本地网卡地址, 多个地址用逗号隔开,例如: 127.0.0.1,192.168.100.126"}, + []string{"local_addrs", c.LocalAddrs, "", "绑定本地网卡地址, 多个地址用逗号隔开,支持网口名称,例如: 127.0.0.1,192.168.100.126,en0,eth0"}, []string{"ip_type", c.PreferIPType, "ipv4-优先IPv4,ipv6-优先IPv6", "设置域名解析IP优先类型。修改后需要重启应用生效"}, []string{"file_record_config", fileRecorderLabel, "1-开启,2-禁用", "设置是否开启上传、下载、同步文件的结果记录,开启后会把结果记录到CSV文件方便后期查看"}, []string{"device_id", c.DeviceId, "", "客户端ID,用于标识登录客户端,阿里单个账号最多允许10个客户端同时在线。修改后需要重启应用生效"}, diff --git a/internal/config/utils.go b/internal/config/utils.go index 41f7d41..e01dc73 100644 --- a/internal/config/utils.go +++ b/internal/config/utils.go @@ -17,11 +17,13 @@ import ( "encoding/hex" "github.com/olekukonko/tablewriter" "github.com/tickstep/aliyunpan/cmder/cmdtable" + "github.com/tickstep/aliyunpan/library/nets" "github.com/tickstep/library-go/converter" "github.com/tickstep/library-go/crypto" "github.com/tickstep/library-go/ids" "github.com/tickstep/library-go/logger" "math/rand" + "net" "os" "strconv" "strings" @@ -135,3 +137,30 @@ func RandomDeviceId() string { } return str.String() } + +// ParseLocalAddress 解析网络接口配置为对应的本地IP地址 +func ParseLocalAddress(localAddrs string) []string { + allLocalAddress, _ := nets.GetLocalNetInterfaceAddress() + localAddrNames := strings.Split(localAddrs, ",") + ips := []string{} + for _, addr := range localAddrNames { + if addr == "" { + continue + } + if net.ParseIP(addr) == nil { + // maybe local interface name + if localAddr := allLocalAddress.GetByName(addr); localAddr != nil { + if localAddr.IPv4 != "" { + ips = append(ips, localAddr.IPv4) + } + if localAddr.IPv6 != "" { + ips = append(ips, localAddr.IPv6) + } + } + } else { + // ip + ips = append(ips, addr) + } + } + return ips +} diff --git a/library/nets/util.go b/library/nets/util.go new file mode 100644 index 0000000..18c2f16 --- /dev/null +++ b/library/nets/util.go @@ -0,0 +1,59 @@ +package nets + +import ( + "net" + "strings" +) + +type NetInterfaceInfoList []*NetInterfaceInfo +type NetInterfaceInfo struct { + Name string `json:"name"` + Mac string `json:"mac"` + IPv4 string `json:"ipv4"` + IPv6 string `json:"ipv6"` +} + +func (n *NetInterfaceInfoList) GetByName(name string) *NetInterfaceInfo { + for _, v := range *n { + if v.Name == name { + return v + } + } + return nil +} + +// GetLocalNetInterfaceAddress 获取本地接口地址信息 +func GetLocalNetInterfaceAddress() (NetInterfaceInfoList, error) { + interfaces, err := net.Interfaces() + if err != nil { + return nil, err + } + netList := NetInterfaceInfoList{} + for _, inter := range interfaces { + netInfo := &NetInterfaceInfo{ + Name: inter.Name, + Mac: inter.HardwareAddr.String(), + IPv4: "", + IPv6: "", + } + addrs, err2 := inter.Addrs() + if err2 != nil { + continue + } + for _, address := range addrs { + if ipnet, ok := address.(*net.IPNet); ok { + if ipnet.IP.To4() != nil { // ipv4 + if ipnet.IP.String() != "" { + netInfo.IPv4 = ipnet.IP.String() + } + } else if ipnet.IP.To16() != nil && !ipnet.IP.IsLoopback() { // ipv6 + if ipnet.IP.String() != "" && !strings.HasPrefix(ipnet.IP.String(), "fe80") { // 去掉本地IPv6地址 + netInfo.IPv6 = ipnet.IP.String() + } + } + } + } + netList = append(netList, netInfo) + } + return netList, nil +}