diff --git a/client/client.go b/client/client.go index 504bb1b..3ae167b 100755 --- a/client/client.go +++ b/client/client.go @@ -9,8 +9,8 @@ import ( "time" "github.com/astaxie/beego/logs" - "github.com/xtaci/kcp-go" - + "github.com/xtaci/kcp-go" + "github.com/cnlh/nps/lib/common" "github.com/cnlh/nps/lib/config" "github.com/cnlh/nps/lib/conn" @@ -158,7 +158,7 @@ func (s *TRPClient) newChan() { func (s *TRPClient) handleChan(src net.Conn) { lk, err := conn.NewConn(src).GetLinkInfo() - if err != nil { + if err != nil || lk == nil { src.Close() logs.Error("get connection info from server error ", err) return @@ -245,7 +245,6 @@ func (s *TRPClient) handleUdp(serverConn net.Conn) { logs.Error("unpack data error", err.Error()) return } - raddr, err := net.ResolveUDPAddr("udp", udpData.Header.Addr.String()) if err != nil { logs.Error("build remote addr err", err.Error()) diff --git a/lib/common/util.go b/lib/common/util.go index 1de4455..67f58cb 100755 --- a/lib/common/util.go +++ b/lib/common/util.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/base64" "encoding/binary" + "errors" "html/template" "io" "io/ioutil" @@ -397,13 +398,61 @@ func GetExtFromPath(path string) string { return string(re.Find([]byte(s[0]))) } +var externalIp string func GetExternalIp() string { + if externalIp != "" { + return externalIp + } resp, err := http.Get("http://myexternalip.com/raw") if err != nil { return "" } defer resp.Body.Close() content, _ := ioutil.ReadAll(resp.Body) - return string(content) + externalIp = string(content) + return externalIp +} + +func GetIntranetIp() (error, string) { + addrs, err := net.InterfaceAddrs() + if err != nil { + return nil, "" + } + for _, address := range addrs { + // 检查ip地址判断是否回环地址 + if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { + if ipnet.IP.To4() != nil { + return nil, ipnet.IP.To4().String() + } + } + } + return errors.New("get intranet ip error"), "" +} + +func IsPublicIP(IP net.IP) bool { + if IP.IsLoopback() || IP.IsLinkLocalMulticast() || IP.IsLinkLocalUnicast() { + return false + } + if ip4 := IP.To4(); ip4 != nil { + switch true { + case ip4[0] == 10: + return false + case ip4[0] == 172 && ip4[1] >= 16 && ip4[1] <= 31: + return false + case ip4[0] == 192 && ip4[1] == 168: + return false + default: + return true + } + } + return false +} + +func GetServerIpByClientIp(clientIp net.IP) string { + if IsPublicIP(clientIp) { + return GetExternalIp() + } + _, ip := GetIntranetIp() + return ip } diff --git a/lib/conn/conn.go b/lib/conn/conn.go index 9f0c397..8f19e6c 100755 --- a/lib/conn/conn.go +++ b/lib/conn/conn.go @@ -124,8 +124,8 @@ func (s *Conn) SetAlive(tp string) { case *net.TCPConn: conn := s.Conn.(*net.TCPConn) conn.SetReadDeadline(time.Time{}) - conn.SetKeepAlive(true) - conn.SetKeepAlivePeriod(time.Duration(2 * time.Second)) + //conn.SetKeepAlive(false) + //conn.SetKeepAlivePeriod(time.Duration(2 * time.Second)) case *mux.PortConn: s.Conn.(*mux.PortConn).SetReadDeadline(time.Time{}) } diff --git a/server/proxy/socks5.go b/server/proxy/socks5.go index ea78fd8..91fb451 100755 --- a/server/proxy/socks5.go +++ b/server/proxy/socks5.go @@ -3,7 +3,6 @@ package proxy import ( "encoding/binary" "errors" - "fmt" "io" "net" "strconv" @@ -174,12 +173,7 @@ func (s *Sock5ModeServer) sendUdpReply(writeConn net.Conn, c net.Conn, rep uint8 } -var serveExternalIp string - func (s *Sock5ModeServer) handleUDP(c net.Conn) { - if serveExternalIp == "" { - serveExternalIp = common.GetExternalIp() - } defer c.Close() addrType := make([]byte, 1) c.Read(addrType) @@ -206,7 +200,7 @@ func (s *Sock5ModeServer) handleUDP(c net.Conn) { //读取端口 var port uint16 binary.Read(c, binary.BigEndian, &port) - fmt.Println(host, string(port)) + logs.Warn(host, string(port)) replyAddr, err := net.ResolveUDPAddr("udp", s.task.ServerIp+":0") if err != nil { logs.Error("build local reply addr error", err) @@ -219,9 +213,8 @@ func (s *Sock5ModeServer) handleUDP(c net.Conn) { return } // reply the local addr - s.sendUdpReply(c, reply, succeeded, serveExternalIp) + s.sendUdpReply(c, reply, succeeded, common.GetServerIpByClientIp(c.RemoteAddr().(*net.TCPAddr).IP)) defer reply.Close() - // new a tunnel to client link := conn.NewLink("udp", "", s.task.Client.Cnf.Crypt, s.task.Client.Cnf.Compress, c.RemoteAddr().String(), false) target, err := s.bridge.SendLinkInfo(s.task.Client.Id, link, s.task)