调整策略

This commit is contained in:
kony
2025-01-12 14:21:16 +08:00
parent 8c1a4e0f7e
commit 71f711373e
14 changed files with 766 additions and 12 deletions

View File

@@ -4,5 +4,5 @@ Website = "https://goodlink.kony.vip"
Icon = "theme/favicon.png"
Name = "goodlink-windows-amd64-ui"
ID = "goodlink.kony.vip"
Version = "1.14.25"
Version = "1.14.26"
Build = 0

View File

@@ -38,8 +38,8 @@ func Help() {
flag.IntVar(&Arg_p2p_timeout, "time_out", 30, "最大连接超时, 单位: 秒")
flag.IntVar(&Arg_conn_type, "conn", 0, "若超过10分钟无法连接, 可尝试更换连接方式: 0: 主动; 1: 被动")
flag.IntVar(&Arg_conn_n0, "n0", 64, "dev n0")
flag.IntVar(&Arg_conn_n1, "n1", 16, "dev n1")
flag.IntVar(&Arg_conn_n0, "n0", 256, "dev n0")
flag.IntVar(&Arg_conn_n1, "n1", 1, "dev n1")
/* 没有用到的参数 */
flag.Bool("fork", false, "子进程")

View File

@@ -44,10 +44,10 @@ func Init(m_cli_redis_addr, m_cli_redis_pass string, m_cli_redis_id int) error {
Addr: m_cli_redis_addr,
Password: m_cli_redis_pass,
DB: m_cli_redis_id,
MaxRetries: 99,
DialTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
WriteTimeout: 15 * time.Second,
//MaxRetries: 99,
DialTimeout: 5 * time.Second,
ReadTimeout: 5 * time.Second,
WriteTimeout: 5 * time.Second,
})
if m_redis_db == nil {
return errors.New("Redis失败, 请重启程序")

View File

@@ -80,12 +80,13 @@ func GetLocalQuicConn(conn_type int, count int) (quic.Connection, quic.Stream, e
}
m_tun_passive = tun.CteateTunPassive(conn, redisJson.ServerIP, redisJson.ServerPort1, redisJson.ServerPort2, redisJson.SendPortCount)
m_tun_passive.Start()
redisJson.State = 2
gogo.Log().DebugF("%d: 发送本端地址: %v", redisJson.State, redisJson)
RedisSet(redisJson.RedisTimeOut, &redisJson)
m_tun_passive.Start()
default:
if m_tun_active != nil {
m_tun_active.Release()

View File

@@ -99,13 +99,15 @@ func GetRemoteQuicConn(time_out time.Duration) (quic.Connection, quic.Stream) {
m_tun_active = nil
m_tun_passive = tun.CteateTunPassive(conn, redisJson.ClientIP, redisJson.ClientPort1, redisJson.ClientPort2, 0x100)
m_tun_passive.Start()
tun_passive_chain = m_tun_passive.GetChain()
redisJson.State = 1
gogo.Log().DebugF("%d: 发送本端地址: %v", redisJson.State, redisJson)
RedisSet(redisJson.RedisTimeOut, &redisJson)
m_tun_passive.Start()
}
case 2:

72
upnp/AddPortMapping.go Normal file
View File

@@ -0,0 +1,72 @@
package upnp
import (
// "log"
// "fmt"
"io/ioutil"
"net/http"
"strconv"
"strings"
)
type AddPortMapping struct {
upnp *Upnp
}
func (this *AddPortMapping) Send(localPort, remotePort int, protocol string) bool {
request := this.buildRequest(localPort, remotePort, protocol)
response, _ := http.DefaultClient.Do(request)
resultBody, _ := ioutil.ReadAll(response.Body)
if response.StatusCode == 200 {
this.resolve(string(resultBody))
return true
}
return false
}
func (this *AddPortMapping) buildRequest(localPort, remotePort int, protocol string) *http.Request {
//请求头
header := http.Header{}
header.Set("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2")
header.Set("SOAPAction", `"urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"`)
header.Set("Content-Type", "text/xml")
header.Set("Connection", "Close")
header.Set("Content-Length", "")
//请求体
body := Node{Name: "SOAP-ENV:Envelope",
Attr: map[string]string{"xmlns:SOAP-ENV": `"http://schemas.xmlsoap.org/soap/envelope/"`,
"SOAP-ENV:encodingStyle": `"http://schemas.xmlsoap.org/soap/encoding/"`}}
childOne := Node{Name: `SOAP-ENV:Body`}
childTwo := Node{Name: `m:AddPortMapping`,
Attr: map[string]string{"xmlns:m": `"urn:schemas-upnp-org:service:WANIPConnection:1"`}}
childList1 := Node{Name: "NewExternalPort", Content: strconv.Itoa(remotePort)}
childList2 := Node{Name: "NewInternalPort", Content: strconv.Itoa(localPort)}
childList3 := Node{Name: "NewProtocol", Content: protocol}
childList4 := Node{Name: "NewEnabled", Content: "1"}
childList5 := Node{Name: "NewInternalClient", Content: this.upnp.LocalHost}
childList6 := Node{Name: "NewLeaseDuration", Content: "0"}
childList7 := Node{Name: "NewPortMappingDescription", Content: "mandela"}
childList8 := Node{Name: "NewRemoteHost"}
childTwo.AddChild(childList1)
childTwo.AddChild(childList2)
childTwo.AddChild(childList3)
childTwo.AddChild(childList4)
childTwo.AddChild(childList5)
childTwo.AddChild(childList6)
childTwo.AddChild(childList7)
childTwo.AddChild(childList8)
childOne.AddChild(childTwo)
body.AddChild(childOne)
bodyStr := body.BuildXML()
//请求
request, _ := http.NewRequest("POST", "http://"+this.upnp.Gateway.Host+this.upnp.CtrlUrl,
strings.NewReader(bodyStr))
request.Header = header
request.Header.Set("Content-Length", strconv.Itoa(len([]byte(bodyStr))))
return request
}
func (this *AddPortMapping) resolve(resultStr string) {
}

61
upnp/DelPortMapping.go Normal file
View File

@@ -0,0 +1,61 @@
package upnp
import (
"io/ioutil"
// "log"
"net/http"
"strconv"
"strings"
)
type DelPortMapping struct {
upnp *Upnp
}
func (this *DelPortMapping) Send(remotePort int, protocol string) bool {
request := this.buildRequest(remotePort, protocol)
response, _ := http.DefaultClient.Do(request)
resultBody, _ := ioutil.ReadAll(response.Body)
if response.StatusCode == 200 {
// log.Println(string(resultBody))
this.resolve(string(resultBody))
return true
}
return false
}
func (this *DelPortMapping) buildRequest(remotePort int, protocol string) *http.Request {
//请求头
header := http.Header{}
header.Set("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2")
header.Set("SOAPAction", `"urn:schemas-upnp-org:service:WANIPConnection:1#DeletePortMapping"`)
header.Set("Content-Type", "text/xml")
header.Set("Connection", "Close")
header.Set("Content-Length", "")
//请求体
body := Node{Name: "SOAP-ENV:Envelope",
Attr: map[string]string{"xmlns:SOAP-ENV": `"http://schemas.xmlsoap.org/soap/envelope/"`,
"SOAP-ENV:encodingStyle": `"http://schemas.xmlsoap.org/soap/encoding/"`}}
childOne := Node{Name: `SOAP-ENV:Body`}
childTwo := Node{Name: `m:DeletePortMapping`,
Attr: map[string]string{"xmlns:m": `"urn:schemas-upnp-org:service:WANIPConnection:1"`}}
childList1 := Node{Name: "NewExternalPort", Content: strconv.Itoa(remotePort)}
childList2 := Node{Name: "NewProtocol", Content: protocol}
childList3 := Node{Name: "NewRemoteHost"}
childTwo.AddChild(childList1)
childTwo.AddChild(childList2)
childTwo.AddChild(childList3)
childOne.AddChild(childTwo)
body.AddChild(childOne)
bodyStr := body.BuildXML()
//请求
request, _ := http.NewRequest("POST", "http://"+this.upnp.Gateway.Host+this.upnp.CtrlUrl,
strings.NewReader(bodyStr))
request.Header = header
request.Header.Set("Content-Length", strconv.Itoa(len([]byte(bodyStr))))
return request
}
func (this *DelPortMapping) resolve(resultStr string) {
}

97
upnp/DeviceDesc.go Normal file
View File

@@ -0,0 +1,97 @@
package upnp
import (
"encoding/xml"
"io/ioutil"
"net/http"
"strings"
)
type DeviceDesc struct {
upnp *Upnp
}
func (this *DeviceDesc) Send() bool {
request := this.BuildRequest()
response, _ := http.DefaultClient.Do(request)
resultBody, _ := ioutil.ReadAll(response.Body)
if response.StatusCode == 200 {
this.resolve(string(resultBody))
return true
}
return false
}
func (this *DeviceDesc) BuildRequest() *http.Request {
//请求头
header := http.Header{}
header.Set("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2")
header.Set("User-Agent", "preston")
header.Set("Host", this.upnp.Gateway.Host)
header.Set("Connection", "keep-alive")
//请求
request, _ := http.NewRequest("GET", "http://"+this.upnp.Gateway.Host+this.upnp.Gateway.DeviceDescUrl, nil)
request.Header = header
// request := http.Request{Method: "GET", Proto: "HTTP/1.1",
// Host: this.upnp.Gateway.Host, Url: this.upnp.Gateway.DeviceDescUrl, Header: header}
return request
}
func (this *DeviceDesc) resolve(resultStr string) {
inputReader := strings.NewReader(resultStr)
// 从文件读取,如可以如下:
// content, err := ioutil.ReadFile("studygolang.xml")
// decoder := xml.NewDecoder(bytes.NewBuffer(content))
lastLabel := ""
ISUpnpServer := false
IScontrolURL := false
var controlURL string //`controlURL`
// var eventSubURL string //`eventSubURL`
// var SCPDURL string //`SCPDURL`
decoder := xml.NewDecoder(inputReader)
for t, err := decoder.Token(); err == nil && !IScontrolURL; t, err = decoder.Token() {
switch token := t.(type) {
// 处理元素开始(标签)
case xml.StartElement:
if ISUpnpServer {
name := token.Name.Local
lastLabel = name
}
// 处理元素结束(标签)
case xml.EndElement:
// log.Println("结束标记:", token.Name.Local)
// 处理字符数据(这里就是元素的文本)
case xml.CharData:
//得到url后其他标记就不处理了
content := string([]byte(token))
//找到提供端口映射的服务
if content == this.upnp.Gateway.ServiceType {
ISUpnpServer = true
continue
}
//urn:upnp-org:serviceId:WANIPConnection
if ISUpnpServer {
switch lastLabel {
case "controlURL":
controlURL = content
IScontrolURL = true
case "eventSubURL":
// eventSubURL = content
case "SCPDURL":
// SCPDURL = content
}
}
default:
// ...
}
}
this.upnp.CtrlUrl = controlURL
}

45
upnp/DeviceStatusInfo.go Normal file
View File

@@ -0,0 +1,45 @@
package upnp
import (
// "log"
// "io/ioutil"
"net/http"
"strconv"
"strings"
)
type SearchGatewayReq struct {
host string
resultBody string
ctrlUrl string
upnp *Upnp
}
func (this SearchGatewayReq) Send() {
// request := this.BuildRequest()
}
func (this SearchGatewayReq) BuildRequest() *http.Request {
//请求头
header := http.Header{}
header.Set("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2")
header.Set("SOAPAction", `"urn:schemas-upnp-org:service:WANIPConnection:1#GetStatusInfo"`)
header.Set("Content-Type", "text/xml")
header.Set("Connection", "Close")
header.Set("Content-Length", "")
//请求体
body := Node{Name: "SOAP-ENV:Envelope",
Attr: map[string]string{"xmlns:SOAP-ENV": `"http://schemas.xmlsoap.org/soap/envelope/"`,
"SOAP-ENV:encodingStyle": `"http://schemas.xmlsoap.org/soap/encoding/"`}}
childOne := Node{Name: `SOAP-ENV:Body`}
childTwo := Node{Name: `m:GetStatusInfo`,
Attr: map[string]string{"xmlns:m": `"urn:schemas-upnp-org:service:WANIPConnection:1"`}}
childOne.AddChild(childTwo)
body.AddChild(childOne)
bodyStr := body.BuildXML()
//请求
request, _ := http.NewRequest("POST", "http://"+this.upnp.Gateway.Host+this.upnp.CtrlUrl,
strings.NewReader(bodyStr))
request.Header = header
request.Header.Set("Content-Length", strconv.Itoa(len([]byte(bodyStr))))
return request
}

78
upnp/ExternalIPAddress.go Normal file
View File

@@ -0,0 +1,78 @@
package upnp
import (
"encoding/xml"
"io/ioutil"
// "log"
"net/http"
"strconv"
"strings"
)
type ExternalIPAddress struct {
upnp *Upnp
}
func (this *ExternalIPAddress) Send() bool {
request := this.BuildRequest()
response, _ := http.DefaultClient.Do(request)
resultBody, _ := ioutil.ReadAll(response.Body)
if response.StatusCode == 200 {
this.resolve(string(resultBody))
return true
}
return false
}
func (this *ExternalIPAddress) BuildRequest() *http.Request {
//请求头
header := http.Header{}
header.Set("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2")
header.Set("SOAPAction", `"urn:schemas-upnp-org:service:WANIPConnection:1#GetExternalIPAddress"`)
header.Set("Content-Type", "text/xml")
header.Set("Connection", "Close")
header.Set("Content-Length", "")
//请求体
body := Node{Name: "SOAP-ENV:Envelope",
Attr: map[string]string{"xmlns:SOAP-ENV": `"http://schemas.xmlsoap.org/soap/envelope/"`,
"SOAP-ENV:encodingStyle": `"http://schemas.xmlsoap.org/soap/encoding/"`}}
childOne := Node{Name: `SOAP-ENV:Body`}
childTwo := Node{Name: `m:GetExternalIPAddress`,
Attr: map[string]string{"xmlns:m": `"urn:schemas-upnp-org:service:WANIPConnection:1"`}}
childOne.AddChild(childTwo)
body.AddChild(childOne)
bodyStr := body.BuildXML()
//请求
request, _ := http.NewRequest("POST", "http://"+this.upnp.Gateway.Host+this.upnp.CtrlUrl,
strings.NewReader(bodyStr))
request.Header = header
request.Header.Set("Content-Length", strconv.Itoa(len([]byte(body.BuildXML()))))
return request
}
//NewExternalIPAddress
func (this *ExternalIPAddress) resolve(resultStr string) {
inputReader := strings.NewReader(resultStr)
decoder := xml.NewDecoder(inputReader)
ISexternalIP := false
for t, err := decoder.Token(); err == nil; t, err = decoder.Token() {
switch token := t.(type) {
// 处理元素开始(标签)
case xml.StartElement:
name := token.Name.Local
if name == "NewExternalIPAddress" {
ISexternalIP = true
}
// 处理元素结束(标签)
case xml.EndElement:
// 处理字符数据(这里就是元素的文本)
case xml.CharData:
if ISexternalIP == true {
this.upnp.GatewayOutsideIP = string([]byte(token))
return
}
default:
// ...
}
}
}

121
upnp/SearchGatewayMsg.go Normal file
View File

@@ -0,0 +1,121 @@
package upnp
import (
"log"
"net"
"strings"
"time"
// "net/http"
)
type Gateway struct {
GatewayName string //网关名称
Host string //网关ip和端口
DeviceDescUrl string //网关设备描述路径
Cache string //cache
ST string
USN string
deviceType string //设备的urn "urn:schemas-upnp-org:service:WANIPConnection:1"
ControlURL string //设备端口映射请求路径
ServiceType string //提供upnp服务的服务类型
}
type SearchGateway struct {
searchMessage string
upnp *Upnp
}
func (this *SearchGateway) Send() bool {
this.buildRequest()
c := make(chan string)
go this.send(c)
result := <-c
if result == "" {
//超时了
this.upnp.Active = false
return false
}
this.resolve(result)
this.upnp.Gateway.ServiceType = "urn:schemas-upnp-org:service:WANIPConnection:1"
this.upnp.Active = true
return true
}
func (this *SearchGateway) send(c chan string) {
//发送组播消息,要带上端口,格式如:"239.255.255.250:1900"
var conn *net.UDPConn
defer func() {
if r := recover(); r != nil {
//超时了
}
}()
go func(conn *net.UDPConn) {
defer func() {
if r := recover(); r != nil {
//没超时
}
}()
//超时时间为3秒
time.Sleep(time.Second * 3)
c <- ""
conn.Close()
}(conn)
remotAddr, err := net.ResolveUDPAddr("udp", "239.255.255.250:1900")
if err != nil {
log.Println("组播地址格式不正确")
}
locaAddr, err := net.ResolveUDPAddr("udp", this.upnp.LocalHost+":")
if err != nil {
log.Println("本地ip地址格式不正确")
}
conn, err = net.ListenUDP("udp", locaAddr)
defer conn.Close()
if err != nil {
log.Println("监听udp出错")
}
_, err = conn.WriteToUDP([]byte(this.searchMessage), remotAddr)
if err != nil {
log.Println("发送msg到组播地址出错")
}
buf := make([]byte, 1024)
n, _, err := conn.ReadFromUDP(buf)
if err != nil {
log.Println("从组播地址接搜消息出错")
}
result := string(buf[:n])
c <- result
}
func (this *SearchGateway) buildRequest() {
this.searchMessage = "M-SEARCH * HTTP/1.1\r\n" +
"HOST: 239.255.255.250:1900\r\n" +
"ST: urn:schemas-upnp-org:service:WANIPConnection:1\r\n" +
"MAN: \"ssdp:discover\"\r\n" + "MX: 3\r\n\r\n"
}
func (this *SearchGateway) resolve(result string) {
this.upnp.Gateway = &Gateway{}
lines := strings.Split(result, "\r\n")
for _, line := range lines {
//按照第一个冒号分为两个字符串
nameValues := strings.SplitAfterN(line, ":", 2)
if len(nameValues) < 2 {
continue
}
switch strings.ToUpper(strings.Trim(strings.Split(nameValues[0], ":")[0], " ")) {
case "ST":
this.upnp.Gateway.ST = nameValues[1]
case "CACHE-CONTROL":
this.upnp.Gateway.Cache = nameValues[1]
case "LOCATION":
urls := strings.Split(strings.Split(nameValues[1], "//")[1], "/")
this.upnp.Gateway.Host = urls[0]
this.upnp.Gateway.DeviceDescUrl = "/" + urls[1]
case "SERVER":
this.upnp.Gateway.GatewayName = nameValues[1]
default:
}
}
}

51
upnp/common.go Normal file
View File

@@ -0,0 +1,51 @@
package upnp
import (
// "log"
"errors"
"log"
"net"
"strings"
)
// 获取本机能联网的ip地址
func GetLocalIntenetIp() string {
/*
获得所有本机地址
判断能联网的ip地址
*/
conn, err := net.Dial("udp4", "124.223.50.150:13478")
if err != nil {
panic(errors.New("不能连接网络"))
}
defer conn.Close()
log.Println(conn.LocalAddr().String())
log.Println(strings.Split(conn.LocalAddr().String(), ":")[0])
return strings.Split(conn.LocalAddr().String(), ":")[0]
}
// This returns the list of local ip addresses which other hosts can connect
// to (NOTE: Loopback ip is ignored).
func GetLocalIPs() ([]*net.IP, error) {
addrs, err := net.InterfaceAddrs()
if err != nil {
return nil, err
}
ips := make([]*net.IP, 0)
for _, addr := range addrs {
ipnet, ok := addr.(*net.IPNet)
if !ok {
continue
}
if ipnet.IP.IsLoopback() {
continue
}
ips = append(ips, &ipnet.IP)
}
return ips, nil
}

31
upnp/message.go Normal file
View File

@@ -0,0 +1,31 @@
package upnp
import (
"bytes"
)
type Node struct {
Name string
Content string
Attr map[string]string
Child []Node
}
func (n *Node) AddChild(node Node) {
n.Child = append(n.Child, node)
}
func (n *Node) BuildXML() string {
buf := bytes.NewBufferString("<")
buf.WriteString(n.Name)
for key, value := range n.Attr {
buf.WriteString(" ")
buf.WriteString(key + "=" + value)
}
buf.WriteString(">" + n.Content)
for _, node := range n.Child {
buf.WriteString(node.BuildXML())
}
buf.WriteString("</" + n.Name + ">")
return buf.String()
}

195
upnp/upnp.go Normal file
View File

@@ -0,0 +1,195 @@
package upnp
import (
// "fmt"
"errors"
"log"
"sync"
)
/*
* 得到网关
*/
//对所有的端口进行管理
type MappingPortStruct struct {
lock *sync.Mutex
mappingPorts map[string][][]int
}
//添加一个端口映射记录
//只对映射进行管理
func (this *MappingPortStruct) addMapping(localPort, remotePort int, protocol string) {
this.lock.Lock()
defer this.lock.Unlock()
if this.mappingPorts == nil {
one := make([]int, 0)
one = append(one, localPort)
two := make([]int, 0)
two = append(two, remotePort)
portMapping := [][]int{one, two}
this.mappingPorts = map[string][][]int{protocol: portMapping}
return
}
portMapping := this.mappingPorts[protocol]
if portMapping == nil {
one := make([]int, 0)
one = append(one, localPort)
two := make([]int, 0)
two = append(two, remotePort)
this.mappingPorts[protocol] = [][]int{one, two}
return
}
one := portMapping[0]
two := portMapping[1]
one = append(one, localPort)
two = append(two, remotePort)
this.mappingPorts[protocol] = [][]int{one, two}
}
//删除一个映射记录
//只对映射进行管理
func (this *MappingPortStruct) delMapping(remotePort int, protocol string) {
this.lock.Lock()
defer this.lock.Unlock()
if this.mappingPorts == nil {
return
}
tmp := MappingPortStruct{lock: new(sync.Mutex)}
mappings := this.mappingPorts[protocol]
for i := 0; i < len(mappings[0]); i++ {
if mappings[1][i] == remotePort {
//要删除的映射
break
}
tmp.addMapping(mappings[0][i], mappings[1][i], protocol)
}
this.mappingPorts = tmp.mappingPorts
}
func (this *MappingPortStruct) GetAllMapping() map[string][][]int {
return this.mappingPorts
}
type Upnp struct {
Active bool //这个upnp协议是否可用
LocalHost string //本机ip地址
GatewayInsideIP string //局域网网关ip
GatewayOutsideIP string //网关公网ip
OutsideMappingPort map[string]int //映射外部端口
InsideMappingPort map[string]int //映射本机端口
Gateway *Gateway //网关信息
CtrlUrl string //控制请求url
MappingPort MappingPortStruct //已经添加了的映射 {"TCP":[1990],"UDP":[1991]}
}
//得到本地联网的ip地址
//得到局域网网关ip
func (this *Upnp) SearchGateway() (err error) {
defer func(err error) {
if errTemp := recover(); errTemp != nil {
log.Println("upnp模块报错了", errTemp)
err = errTemp.(error)
}
}(err)
if this.LocalHost == "" {
this.MappingPort = MappingPortStruct{
lock: new(sync.Mutex),
// mappingPorts: map[string][][]int{},
}
this.LocalHost = GetLocalIntenetIp()
}
searchGateway := SearchGateway{upnp: this}
if searchGateway.Send() {
return nil
}
return errors.New("未发现网关设备")
}
func (this *Upnp) deviceStatus() {
}
//查看设备描述得到控制请求url
func (this *Upnp) deviceDesc() (err error) {
if this.GatewayInsideIP == "" {
if err := this.SearchGateway(); err != nil {
return err
}
}
device := DeviceDesc{upnp: this}
device.Send()
this.Active = true
// log.Println("获得控制请求url:", this.CtrlUrl)
return
}
//查看公网ip地址
func (this *Upnp) ExternalIPAddr() (err error) {
if this.CtrlUrl == "" {
if err := this.deviceDesc(); err != nil {
return err
}
}
eia := ExternalIPAddress{upnp: this}
eia.Send()
return nil
// log.Println("获得公网ip地址为", this.GatewayOutsideIP)
}
//添加一个端口映射
func (this *Upnp) AddPortMapping(localPort, remotePort int, protocol string) (err error) {
defer func(err error) {
if errTemp := recover(); errTemp != nil {
log.Println("upnp模块报错了", errTemp)
err = errTemp.(error)
}
}(err)
if this.GatewayOutsideIP == "" {
if err := this.ExternalIPAddr(); err != nil {
return err
}
}
addPort := AddPortMapping{upnp: this}
if issuccess := addPort.Send(localPort, remotePort, protocol); issuccess {
this.MappingPort.addMapping(localPort, remotePort, protocol)
// log.Println("添加一个端口映射protocol:", protocol, "local:", localPort, "remote:", remotePort)
return nil
} else {
this.Active = false
// log.Println("添加一个端口映射失败")
return errors.New("添加一个端口映射失败")
}
}
func (this *Upnp) DelPortMapping(remotePort int, protocol string) bool {
delMapping := DelPortMapping{upnp: this}
issuccess := delMapping.Send(remotePort, protocol)
if issuccess {
this.MappingPort.delMapping(remotePort, protocol)
log.Println("删除了一个端口映射: remote:", remotePort)
}
return issuccess
}
//回收端口
func (this *Upnp) Reclaim() {
mappings := this.MappingPort.GetAllMapping()
tcpMapping, ok := mappings["TCP"]
if ok {
for i := 0; i < len(tcpMapping[0]); i++ {
this.DelPortMapping(tcpMapping[1][i], "TCP")
}
}
udpMapping, ok := mappings["UDP"]
if ok {
for i := 0; i < len(udpMapping[0]); i++ {
this.DelPortMapping(udpMapping[0][i], "UDP")
}
}
}
func (this *Upnp) GetAllMapping() map[string][][]int {
return this.MappingPort.GetAllMapping()
}