support ipv6

This commit is contained in:
haidy 2019-01-04 22:21:57 +08:00
parent b2e15c752e
commit f2512f8fce
17 changed files with 104 additions and 61 deletions

View File

@ -15,7 +15,6 @@
package client package client
import ( import (
"fmt"
"net" "net"
"net/http" "net/http"
"time" "time"
@ -42,7 +41,7 @@ func (svr *Service) RunAdminServer(addr string, port int) (err error) {
router.HandleFunc("/api/reload", svr.apiReload).Methods("GET") router.HandleFunc("/api/reload", svr.apiReload).Methods("GET")
router.HandleFunc("/api/status", svr.apiStatus).Methods("GET") router.HandleFunc("/api/status", svr.apiStatus).Methods("GET")
address := fmt.Sprintf("%s:%d", addr, port) address := newAddress(addr, port)
server := &http.Server{ server := &http.Server{
Addr: address, Addr: address,
Handler: router, Handler: router,

View File

@ -132,49 +132,57 @@ func NewProxyStatusResp(status *proxy.ProxyStatus) ProxyStatusResp {
switch cfg := status.Cfg.(type) { switch cfg := status.Cfg.(type) {
case *config.TcpProxyConf: case *config.TcpProxyConf:
if cfg.LocalPort != 0 { if cfg.LocalPort != 0 {
psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIp, cfg.LocalPort) psr.LocalAddr = newAddress(cfg.LocalIp, cfg.LocalPort)
} }
psr.Plugin = cfg.Plugin psr.Plugin = cfg.Plugin
if status.Err != "" { if status.Err != "" {
psr.RemoteAddr = fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, cfg.RemotePort) psr.RemoteAddr = newAddress(g.GlbClientCfg.ServerAddr, cfg.RemotePort)
} else { } else {
psr.RemoteAddr = g.GlbClientCfg.ServerAddr + status.RemoteAddr psr.RemoteAddr = g.GlbClientCfg.ServerAddr + status.RemoteAddr
} }
case *config.UdpProxyConf: case *config.UdpProxyConf:
if cfg.LocalPort != 0 { if cfg.LocalPort != 0 {
psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIp, cfg.LocalPort) psr.LocalAddr = newAddress(cfg.LocalIp, cfg.LocalPort)
} }
if status.Err != "" { if status.Err != "" {
psr.RemoteAddr = fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, cfg.RemotePort) psr.RemoteAddr = newAddress(g.GlbClientCfg.ServerAddr, cfg.RemotePort)
} else { } else {
psr.RemoteAddr = g.GlbClientCfg.ServerAddr + status.RemoteAddr psr.RemoteAddr = g.GlbClientCfg.ServerAddr + status.RemoteAddr
} }
case *config.HttpProxyConf: case *config.HttpProxyConf:
if cfg.LocalPort != 0 { if cfg.LocalPort != 0 {
psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIp, cfg.LocalPort) psr.LocalAddr = newAddress(cfg.LocalIp, cfg.LocalPort)
} }
psr.Plugin = cfg.Plugin psr.Plugin = cfg.Plugin
psr.RemoteAddr = status.RemoteAddr psr.RemoteAddr = status.RemoteAddr
case *config.HttpsProxyConf: case *config.HttpsProxyConf:
if cfg.LocalPort != 0 { if cfg.LocalPort != 0 {
psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIp, cfg.LocalPort) psr.LocalAddr = newAddress(cfg.LocalIp, cfg.LocalPort)
} }
psr.Plugin = cfg.Plugin psr.Plugin = cfg.Plugin
psr.RemoteAddr = status.RemoteAddr psr.RemoteAddr = status.RemoteAddr
case *config.StcpProxyConf: case *config.StcpProxyConf:
if cfg.LocalPort != 0 { if cfg.LocalPort != 0 {
psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIp, cfg.LocalPort) psr.LocalAddr = newAddress(cfg.LocalIp, cfg.LocalPort)
} }
psr.Plugin = cfg.Plugin psr.Plugin = cfg.Plugin
case *config.XtcpProxyConf: case *config.XtcpProxyConf:
if cfg.LocalPort != 0 { if cfg.LocalPort != 0 {
psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIp, cfg.LocalPort) psr.LocalAddr = newAddress(cfg.LocalIp, cfg.LocalPort)
} }
psr.Plugin = cfg.Plugin psr.Plugin = cfg.Plugin
} }
return psr return psr
} }
func newAddress(addr string, port int) string {
if strings.Contains(addr, ".") {
return fmt.Sprintf("%s:%d", addr, port)
} else {
return fmt.Sprintf("[%s]:%d", addr, port)
}
}
// api/status // api/status
func (svr *Service) apiStatus(w http.ResponseWriter, r *http.Request) { func (svr *Service) apiStatus(w http.ResponseWriter, r *http.Request) {
var ( var (

View File

@ -15,7 +15,6 @@
package client package client
import ( import (
"fmt"
"io" "io"
"runtime/debug" "runtime/debug"
"sync" "sync"
@ -169,7 +168,7 @@ func (ctl *Control) connectServer() (conn frpNet.Conn, err error) {
conn = frpNet.WrapConn(stream) conn = frpNet.WrapConn(stream)
} else { } else {
conn, err = frpNet.ConnectServerByProxy(g.GlbClientCfg.HttpProxy, g.GlbClientCfg.Protocol, conn, err = frpNet.ConnectServerByProxy(g.GlbClientCfg.HttpProxy, g.GlbClientCfg.Protocol,
fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerPort)) newAddress(g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerPort))
if err != nil { if err != nil {
ctl.Warn("start new connection to server error: %v", err) ctl.Warn("start new connection to server error: %v", err)
return return

View File

@ -19,6 +19,7 @@ import (
"fmt" "fmt"
"io" "io"
"net" "net"
"strings"
"sync" "sync"
"time" "time"
@ -231,6 +232,14 @@ func (pxy *XtcpProxy) Close() {
} }
} }
func newAddress(addr string, port int) string {
if strings.Contains(addr, ".") {
return fmt.Sprintf("%s:%d", addr, port)
} else {
return fmt.Sprintf("[%s]:%d", addr, port)
}
}
func (pxy *XtcpProxy) InWorkConn(conn frpNet.Conn) { func (pxy *XtcpProxy) InWorkConn(conn frpNet.Conn) {
defer conn.Close() defer conn.Close()
var natHoleSidMsg msg.NatHoleSid var natHoleSidMsg msg.NatHoleSid
@ -244,8 +253,8 @@ func (pxy *XtcpProxy) InWorkConn(conn frpNet.Conn) {
ProxyName: pxy.cfg.ProxyName, ProxyName: pxy.cfg.ProxyName,
Sid: natHoleSidMsg.Sid, Sid: natHoleSidMsg.Sid,
} }
raddr, _ := net.ResolveUDPAddr("udp",
fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerUdpPort)) raddr, _ := net.ResolveUDPAddr("udp", newAddress(g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerUdpPort))
clientConn, err := net.DialUDP("udp", nil, raddr) clientConn, err := net.DialUDP("udp", nil, raddr)
defer clientConn.Close() defer clientConn.Close()
@ -321,7 +330,7 @@ type UdpProxy struct {
} }
func (pxy *UdpProxy) Run() (err error) { func (pxy *UdpProxy) Run() (err error) {
pxy.localAddr, err = net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", pxy.cfg.LocalIp, pxy.cfg.LocalPort)) pxy.localAddr, err = net.ResolveUDPAddr("udp", newAddress(pxy.cfg.LocalIp, pxy.cfg.LocalPort))
if err != nil { if err != nil {
return return
} }
@ -440,7 +449,7 @@ func HandleTcpWorkConnection(localInfo *config.LocalSvrConf, proxyPlugin plugin.
workConn.Debug("handle by plugin finished") workConn.Debug("handle by plugin finished")
return return
} else { } else {
localConn, err := frpNet.ConnectServer("tcp", fmt.Sprintf("%s:%d", localInfo.LocalIp, localInfo.LocalPort)) localConn, err := frpNet.ConnectServer("tcp", newAddress(localInfo.LocalIp, localInfo.LocalPort))
if err != nil { if err != nil {
workConn.Close() workConn.Close()
workConn.Error("connect to local service [%s:%d] error: %v", localInfo.LocalIp, localInfo.LocalPort, err) workConn.Error("connect to local service [%s:%d] error: %v", localInfo.LocalIp, localInfo.LocalPort, err)

View File

@ -156,7 +156,7 @@ func (svr *Service) keepControllerWorking() {
// session: if it's not nil, using tcp mux // session: if it's not nil, using tcp mux
func (svr *Service) login() (conn frpNet.Conn, session *fmux.Session, err error) { func (svr *Service) login() (conn frpNet.Conn, session *fmux.Session, err error) {
conn, err = frpNet.ConnectServerByProxy(g.GlbClientCfg.HttpProxy, g.GlbClientCfg.Protocol, conn, err = frpNet.ConnectServerByProxy(g.GlbClientCfg.HttpProxy, g.GlbClientCfg.Protocol,
fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerPort)) newAddress(g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerPort))
if err != nil { if err != nil {
return return
} }

View File

@ -16,7 +16,6 @@ package client
import ( import (
"bytes" "bytes"
"fmt"
"io" "io"
"net" "net"
"strconv" "strconv"
@ -200,8 +199,7 @@ func (sv *XtcpVisitor) handleConn(userConn frpNet.Conn) {
return return
} }
raddr, err := net.ResolveUDPAddr("udp", raddr, err := net.ResolveUDPAddr("udp", newAddress(g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerUdpPort))
fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerUdpPort))
if err != nil { if err != nil {
sv.Error("resolve server UDP addr error") sv.Error("resolve server UDP addr error")
return return
@ -319,7 +317,7 @@ func (sv *XtcpVisitor) handleConn(userConn frpNet.Conn) {
} }
func (sv *XtcpVisitor) sendDetectMsg(addr string, port int, laddr *net.UDPAddr, content []byte) (err error) { func (sv *XtcpVisitor) sendDetectMsg(addr string, port int, laddr *net.UDPAddr, content []byte) (err error) {
daddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", addr, port)) daddr, err := net.ResolveUDPAddr("udp", newAddress(addr, port))
if err != nil { if err != nil {
return err return err
} }

View File

@ -1,4 +1,3 @@
[common] [common]
bind_addr = 127.0.0.1
bind_port = 7000 bind_port = 7000
allow_ports = 7000, 6000 allow_ports = 7000, 6000

View File

@ -1,12 +1,9 @@
package main package main
import ( import (
"log"
"runtime" "runtime"
"strings" "strings"
"time"
"net/http"
_ "net/http/pprof" _ "net/http/pprof"
"github.com/fatedier/frp/cmd/frp" "github.com/fatedier/frp/cmd/frp"
@ -19,28 +16,28 @@ func main() {
frp.RunFrps(path + "/frps.ini") frp.RunFrps(path + "/frps.ini")
ch := make(chan bool) ch := make(chan bool)
go func() { // go func() {
time.Sleep(time.Second * 5) // time.Sleep(time.Second * 5)
frp.RunFrpc(path + "/frpc.ini") // frp.RunFrpc(path + "/frpc.ini")
ch <- true // ch <- true
}() // }()
<-ch // <-ch
go func() { // go func() {
log.Println(http.ListenAndServe("localhost:10000", nil)) // log.Println(http.ListenAndServe("localhost:10000", nil))
}() // }()
// frp.RunFrps("./frps.ini") // // frp.RunFrps("./frps.ini")
log.Println("frps is running: ", frp.IsFrpsRunning()) // log.Println("frps is running: ", frp.IsFrpsRunning())
//frp.StopFrps() // //frp.StopFrps()
//log.Println("frps is running: ", frp.IsFrpsRunning()) // //log.Println("frps is running: ", frp.IsFrpsRunning())
ch = make(chan bool) // ch = make(chan bool)
go func() { // go func() {
time.Sleep(time.Second * 5) // time.Sleep(time.Second * 5)
log.Println("frpc is running: ", frp.IsFrpcRunning()) // log.Println("frpc is running: ", frp.IsFrpcRunning())
frp.StopFrpc() // frp.StopFrpc()
log.Println("frpc is running: ", frp.IsFrpcRunning()) // log.Println("frpc is running: ", frp.IsFrpcRunning())
ch <- true // ch <- true
}() // }()
<-ch <-ch
} }

View File

@ -15,7 +15,6 @@
package server package server
import ( import (
"fmt"
"net" "net"
"net/http" "net/http"
"time" "time"
@ -53,7 +52,7 @@ func RunDashboardServer(addr string, port int) (err error) {
http.Redirect(w, r, "/static/", http.StatusMovedPermanently) http.Redirect(w, r, "/static/", http.StatusMovedPermanently)
}) })
address := fmt.Sprintf("%s:%d", addr, port) address := newAddress(addr, port)
server := &http.Server{ server := &http.Server{
Addr: address, Addr: address,
Handler: router, Handler: router,

View File

@ -17,6 +17,7 @@ package group
import ( import (
"fmt" "fmt"
"net" "net"
"strings"
"sync" "sync"
"github.com/fatedier/frp/server/ports" "github.com/fatedier/frp/server/ports"
@ -87,6 +88,14 @@ func NewTcpGroup(ctl *TcpGroupCtl) *TcpGroup {
} }
} }
func newAddress(addr string, port int) string {
if strings.Contains(addr, ".") {
return fmt.Sprintf("%s:%d", addr, port)
} else {
return fmt.Sprintf("[%s]:%d", addr, port)
}
}
func (tg *TcpGroup) Listen(proxyName string, group string, groupKey string, addr string, port int) (ln *TcpGroupListener, realPort int, err error) { func (tg *TcpGroup) Listen(proxyName string, group string, groupKey string, addr string, port int) (ln *TcpGroupListener, realPort int, err error) {
tg.mu.Lock() tg.mu.Lock()
defer tg.mu.Unlock() defer tg.mu.Unlock()
@ -95,7 +104,7 @@ func (tg *TcpGroup) Listen(proxyName string, group string, groupKey string, addr
if err != nil { if err != nil {
return return
} }
tcpLn, errRet := net.Listen("tcp", fmt.Sprintf("%s:%d", addr, port)) tcpLn, errRet := net.Listen("tcp", newAddress(addr, port))
if errRet != nil { if errRet != nil {
err = errRet err = errRet
return return

View File

@ -4,6 +4,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"net" "net"
"strings"
"sync" "sync"
"time" "time"
) )
@ -132,9 +133,17 @@ func (pm *PortManager) Acquire(name string, port int) (realPort int, err error)
return return
} }
func newAddress(addr string, port int) string {
if strings.Contains(addr, ".") {
return fmt.Sprintf("%s:%d", addr, port)
} else {
return fmt.Sprintf("[%s]:%d", addr, port)
}
}
func (pm *PortManager) isPortAvailable(port int) bool { func (pm *PortManager) isPortAvailable(port int) bool {
if pm.netType == "udp" { if pm.netType == "udp" {
addr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", pm.bindAddr, port)) addr, err := net.ResolveUDPAddr("udp", newAddress(pm.bindAddr, port))
if err != nil { if err != nil {
return false return false
} }
@ -145,7 +154,7 @@ func (pm *PortManager) isPortAvailable(port int) bool {
l.Close() l.Close()
return true return true
} else { } else {
l, err := net.Listen(pm.netType, fmt.Sprintf("%s:%d", pm.bindAddr, port)) l, err := net.Listen(pm.netType, newAddress(pm.bindAddr, port))
if err != nil { if err != nil {
return false return false
} }

View File

@ -500,7 +500,7 @@ func (pxy *UdpProxy) Run() (remoteAddr string, err error) {
remoteAddr = fmt.Sprintf(":%d", pxy.realPort) remoteAddr = fmt.Sprintf(":%d", pxy.realPort)
pxy.cfg.RemotePort = pxy.realPort pxy.cfg.RemotePort = pxy.realPort
addr, errRet := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", g.GlbServerCfg.ProxyBindAddr, pxy.realPort)) addr, errRet := net.ResolveUDPAddr("udp", newAddress(g.GlbServerCfg.ProxyBindAddr, pxy.realPort))
if errRet != nil { if errRet != nil {
err = errRet err = errRet
return return

View File

@ -20,6 +20,7 @@ import (
"io/ioutil" "io/ioutil"
"net" "net"
"net/http" "net/http"
"strings"
"time" "time"
"github.com/fatedier/frp/assets" "github.com/fatedier/frp/assets"
@ -90,6 +91,14 @@ type Service struct {
closedCh chan bool closedCh chan bool
} }
func newAddress(addr string, port int) string {
if strings.Contains(addr, ".") {
return fmt.Sprintf("%s:%d", addr, port)
} else {
return fmt.Sprintf("[%s]:%d", addr, port)
}
}
func NewService() (svr *Service, err error) { func NewService() (svr *Service, err error) {
cfg := &g.GlbServerCfg.ServerCommonConf cfg := &g.GlbServerCfg.ServerCommonConf
svr = &Service{ svr = &Service{
@ -124,7 +133,7 @@ func NewService() (svr *Service, err error) {
} }
// Listen for accepting connections from client. // Listen for accepting connections from client.
ln, err := net.Listen("tcp", fmt.Sprintf("%s:%d", cfg.BindAddr, cfg.BindPort)) ln, err := net.Listen("tcp", newAddress(cfg.BindAddr, cfg.BindPort))
if err != nil { if err != nil {
err = fmt.Errorf("Create server listener error, %v", err) err = fmt.Errorf("Create server listener error, %v", err)
return return
@ -161,7 +170,7 @@ func NewService() (svr *Service, err error) {
}) })
svr.httpReverseProxy = rp svr.httpReverseProxy = rp
address := fmt.Sprintf("%s:%d", cfg.ProxyBindAddr, cfg.VhostHttpPort) address := newAddress(cfg.ProxyBindAddr, cfg.VhostHttpPort)
server := &http.Server{ server := &http.Server{
Addr: address, Addr: address,
Handler: rp, Handler: rp,
@ -186,7 +195,7 @@ func NewService() (svr *Service, err error) {
if httpsMuxOn { if httpsMuxOn {
l = svr.muxer.ListenHttps(1) l = svr.muxer.ListenHttps(1)
} else { } else {
l, err = net.Listen("tcp", fmt.Sprintf("%s:%d", cfg.ProxyBindAddr, cfg.VhostHttpsPort)) l, err = net.Listen("tcp", newAddress(cfg.ProxyBindAddr, cfg.VhostHttpsPort))
if err != nil { if err != nil {
err = fmt.Errorf("Create server listener error, %v", err) err = fmt.Errorf("Create server listener error, %v", err)
return return
@ -204,7 +213,7 @@ func NewService() (svr *Service, err error) {
// Create nat hole controller. // Create nat hole controller.
if cfg.BindUdpPort > 0 { if cfg.BindUdpPort > 0 {
var nc *NatHoleController var nc *NatHoleController
addr := fmt.Sprintf("%s:%d", cfg.BindAddr, cfg.BindUdpPort) addr := newAddress(cfg.BindAddr, cfg.BindUdpPort)
nc, err = NewNatHoleController(addr) nc, err = NewNatHoleController(addr)
if err != nil { if err != nil {
err = fmt.Errorf("Create nat hole controller error, %v", err) err = fmt.Errorf("Create nat hole controller error, %v", err)

View File

@ -17,6 +17,7 @@ package net
import ( import (
"fmt" "fmt"
"net" "net"
"strings"
"github.com/fatedier/frp/utils/log" "github.com/fatedier/frp/utils/log"
@ -31,8 +32,16 @@ type KcpListener struct {
log.Logger log.Logger
} }
func newAddress(addr string, port int) string {
if strings.Contains(addr, ".") {
return fmt.Sprintf("%s:%d", addr, port)
} else {
return fmt.Sprintf("[%s]:%d", addr, port)
}
}
func ListenKcp(bindAddr string, bindPort int) (l *KcpListener, err error) { func ListenKcp(bindAddr string, bindPort int) (l *KcpListener, err error) {
listener, err := kcp.ListenWithOptions(fmt.Sprintf("%s:%d", bindAddr, bindPort), nil, 10, 3) listener, err := kcp.ListenWithOptions(newAddress(bindAddr, bindPort), nil, 10, 3)
if err != nil { if err != nil {
return l, err return l, err
} }

View File

@ -30,7 +30,7 @@ type TcpListener struct {
} }
func ListenTcp(bindAddr string, bindPort int) (l *TcpListener, err error) { func ListenTcp(bindAddr string, bindPort int) (l *TcpListener, err error) {
tcpAddr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", bindAddr, bindPort)) tcpAddr, err := net.ResolveTCPAddr("tcp", newAddress(bindAddr, bindPort))
if err != nil { if err != nil {
return l, err return l, err
} }

View File

@ -169,7 +169,7 @@ type UdpListener struct {
} }
func ListenUDP(bindAddr string, bindPort int) (l *UdpListener, err error) { func ListenUDP(bindAddr string, bindPort int) (l *UdpListener, err error) {
udpAddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", bindAddr, bindPort)) udpAddr, err := net.ResolveUDPAddr("udp", newAddress(bindAddr, bindPort))
if err != nil { if err != nil {
return l, err return l, err
} }

View File

@ -2,7 +2,6 @@ package net
import ( import (
"errors" "errors"
"fmt"
"net" "net"
"net/http" "net/http"
"net/url" "net/url"
@ -59,7 +58,7 @@ func NewWebsocketListener(ln net.Listener) (wl *WebsocketListener) {
} }
func ListenWebsocket(bindAddr string, bindPort int) (*WebsocketListener, error) { func ListenWebsocket(bindAddr string, bindPort int) (*WebsocketListener, error) {
tcpLn, err := net.Listen("tcp", fmt.Sprintf("%s:%d", bindAddr, bindPort)) tcpLn, err := net.Listen("tcp", newAddress(bindAddr, bindPort))
if err != nil { if err != nil {
return nil, err return nil, err
} }