mirror of
https://gitee.com/IrisVega/frp.git
synced 2024-11-01 22:31:29 +08:00
commit
88fcc079e8
36
README.md
36
README.md
@ -6,12 +6,6 @@
|
|||||||
|
|
||||||
[README](README.md) | [中文文档](README_zh.md)
|
[README](README.md) | [中文文档](README_zh.md)
|
||||||
|
|
||||||
## What is frp?
|
|
||||||
|
|
||||||
frp is a fast reverse proxy to help you expose a local server behind a NAT or firewall to the Internet. As of now, it supports **TCP** and **UDP**, as well as **HTTP** and **HTTPS** protocols, where requests can be forwarded to internal services by domain name.
|
|
||||||
|
|
||||||
frp also has a P2P connect mode.
|
|
||||||
|
|
||||||
<h3 align="center">Platinum Sponsors</h3>
|
<h3 align="center">Platinum Sponsors</h3>
|
||||||
<!--platinum sponsors start-->
|
<!--platinum sponsors start-->
|
||||||
|
|
||||||
@ -23,10 +17,27 @@ frp also has a P2P connect mode.
|
|||||||
|
|
||||||
<!--platinum sponsors end-->
|
<!--platinum sponsors end-->
|
||||||
|
|
||||||
|
<h3 align="center">Gold Sponsors</h3>
|
||||||
|
<!--gold sponsors start-->
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://workos.com/?utm_campaign=github_repo&utm_medium=referral&utm_content=frp&utm_source=github" target="_blank">
|
||||||
|
<img width="300px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_workos.png">
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<!--gold sponsors end-->
|
||||||
|
|
||||||
<h3 align="center">Silver Sponsors</h3>
|
<h3 align="center">Silver Sponsors</h3>
|
||||||
|
|
||||||
* Sakura Frp - 欢迎点击 "加入我们"
|
* Sakura Frp - 欢迎点击 "加入我们"
|
||||||
|
|
||||||
|
## What is frp?
|
||||||
|
|
||||||
|
frp is a fast reverse proxy to help you expose a local server behind a NAT or firewall to the Internet. As of now, it supports **TCP** and **UDP**, as well as **HTTP** and **HTTPS** protocols, where requests can be forwarded to internal services by domain name.
|
||||||
|
|
||||||
|
frp also has a P2P connect mode.
|
||||||
|
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
<!-- vim-markdown-toc GFM -->
|
<!-- vim-markdown-toc GFM -->
|
||||||
@ -82,8 +93,7 @@ frp also has a P2P connect mode.
|
|||||||
* [Development Plan](#development-plan)
|
* [Development Plan](#development-plan)
|
||||||
* [Contributing](#contributing)
|
* [Contributing](#contributing)
|
||||||
* [Donation](#donation)
|
* [Donation](#donation)
|
||||||
* [AliPay](#alipay)
|
* [GitHub Sponsors](#github-sponsors)
|
||||||
* [Wechat Pay](#wechat-pay)
|
|
||||||
* [PayPal](#paypal)
|
* [PayPal](#paypal)
|
||||||
|
|
||||||
<!-- vim-markdown-toc -->
|
<!-- vim-markdown-toc -->
|
||||||
@ -1092,15 +1102,11 @@ Interested in getting involved? We would like to help you!
|
|||||||
|
|
||||||
If frp helps you a lot, you can support us by:
|
If frp helps you a lot, you can support us by:
|
||||||
|
|
||||||
frp QQ group: 606194980
|
### GitHub Sponsors
|
||||||
|
|
||||||
### AliPay
|
Support us by [Github Sponsors](https://github.com/sponsors/fatedier).
|
||||||
|
|
||||||

|
You can have your company's logo placed on README file of this project.
|
||||||
|
|
||||||
### Wechat Pay
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
### PayPal
|
### PayPal
|
||||||
|
|
||||||
|
21
README_zh.md
21
README_zh.md
@ -18,6 +18,17 @@ frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP
|
|||||||
|
|
||||||
<!--platinum sponsors end-->
|
<!--platinum sponsors end-->
|
||||||
|
|
||||||
|
<h3 align="center">Gold Sponsors</h3>
|
||||||
|
<!--gold sponsors start-->
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://workos.com/?utm_campaign=github_repo&utm_medium=referral&utm_content=frp&utm_source=github" target="_blank">
|
||||||
|
<img width="300px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_workos.png">
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<!--gold sponsors end-->
|
||||||
|
|
||||||
<h3 align="center">Silver Sponsors</h3>
|
<h3 align="center">Silver Sponsors</h3>
|
||||||
|
|
||||||
* Sakura Frp - 欢迎点击 "加入我们"
|
* Sakura Frp - 欢迎点击 "加入我们"
|
||||||
@ -65,6 +76,12 @@ frp 是一个免费且开源的项目,我们欢迎任何人为其开发和进
|
|||||||
|
|
||||||
如果您觉得 frp 对你有帮助,欢迎给予我们一定的捐助来维持项目的长期发展。
|
如果您觉得 frp 对你有帮助,欢迎给予我们一定的捐助来维持项目的长期发展。
|
||||||
|
|
||||||
|
### GitHub Sponsors
|
||||||
|
|
||||||
|
您可以通过 [GitHub Sponsors](https://github.com/sponsors/fatedier) 赞助我们。
|
||||||
|
|
||||||
|
企业赞助者可以将贵公司的 Logo 以及链接放置在项目 README 文件中。
|
||||||
|
|
||||||
### 知识星球
|
### 知识星球
|
||||||
|
|
||||||
如果您想学习 frp 相关的知识和技术,或者寻求任何帮助及咨询,都可以通过微信扫描下方的二维码付费加入知识星球的官方社群:
|
如果您想学习 frp 相关的知识和技术,或者寻求任何帮助及咨询,都可以通过微信扫描下方的二维码付费加入知识星球的官方社群:
|
||||||
@ -78,7 +95,3 @@ frp 是一个免费且开源的项目,我们欢迎任何人为其开发和进
|
|||||||
### 微信支付捐赠
|
### 微信支付捐赠
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Paypal 捐赠
|
|
||||||
|
|
||||||
海外用户推荐通过 [Paypal](https://www.paypal.me/fatedier) 向我的账户 **fatedier@gmail.com** 进行捐赠。
|
|
||||||
|
11
Release.md
11
Release.md
@ -1,12 +1,3 @@
|
|||||||
### New
|
|
||||||
|
|
||||||
* Added `connect_server_local_ip` in frpc to specify local IP connected to frps.
|
|
||||||
* Added `tcp_mux_keepalive_interval` both in frpc and frps to set `tcp_mux` keepalive interval seconds if `tcp_mux` is enabled. After using this params, you can set `heartbeat_interval` to `-1` to disable application layer heartbeat to reduce traffic usage(Make sure frps is in the latest version).
|
|
||||||
|
|
||||||
### Improve
|
|
||||||
|
|
||||||
* Server Plugin: Added `client_address` in Login Operation.
|
|
||||||
|
|
||||||
### Fix
|
### Fix
|
||||||
|
|
||||||
* Remove authentication for healthz api.
|
* Fixed IPv6 address parse issue.
|
||||||
|
@ -347,22 +347,18 @@ func (pxy *XTCPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
|
|||||||
xl.Trace("get natHoleRespMsg, sid [%s], client address [%s] visitor address [%s]", natHoleRespMsg.Sid, natHoleRespMsg.ClientAddr, natHoleRespMsg.VisitorAddr)
|
xl.Trace("get natHoleRespMsg, sid [%s], client address [%s] visitor address [%s]", natHoleRespMsg.Sid, natHoleRespMsg.ClientAddr, natHoleRespMsg.VisitorAddr)
|
||||||
|
|
||||||
// Send detect message
|
// Send detect message
|
||||||
array := strings.Split(natHoleRespMsg.VisitorAddr, ":")
|
host, portStr, err := net.SplitHostPort(natHoleRespMsg.VisitorAddr)
|
||||||
if len(array) <= 1 {
|
if err != nil {
|
||||||
xl.Error("get NatHoleResp visitor address error: %v", natHoleRespMsg.VisitorAddr)
|
xl.Error("get NatHoleResp visitor address [%s] error: %v", natHoleRespMsg.VisitorAddr, err)
|
||||||
}
|
}
|
||||||
laddr, _ := net.ResolveUDPAddr("udp", clientConn.LocalAddr().String())
|
laddr, _ := net.ResolveUDPAddr("udp", clientConn.LocalAddr().String())
|
||||||
/*
|
|
||||||
for i := 1000; i < 65000; i++ {
|
port, err := strconv.ParseInt(portStr, 10, 64)
|
||||||
pxy.sendDetectMsg(array[0], int64(i), laddr, "a")
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
port, err := strconv.ParseInt(array[1], 10, 64)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
xl.Error("get natHoleResp visitor address error: %v", natHoleRespMsg.VisitorAddr)
|
xl.Error("get natHoleResp visitor address error: %v", natHoleRespMsg.VisitorAddr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
pxy.sendDetectMsg(array[0], int(port), laddr, []byte(natHoleRespMsg.Sid))
|
pxy.sendDetectMsg(host, int(port), laddr, []byte(natHoleRespMsg.Sid))
|
||||||
xl.Trace("send all detect msg done")
|
xl.Trace("send all detect msg done")
|
||||||
|
|
||||||
msg.WriteMsg(conn, &msg.NatHoleClientDetectOK{})
|
msg.WriteMsg(conn, &msg.NatHoleClientDetectOK{})
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -85,7 +86,7 @@ type STCPVisitor struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (sv *STCPVisitor) Run() (err error) {
|
func (sv *STCPVisitor) Run() (err error) {
|
||||||
sv.l, err = net.Listen("tcp", fmt.Sprintf("%s:%d", sv.cfg.BindAddr, sv.cfg.BindPort))
|
sv.l, err = net.Listen("tcp", net.JoinHostPort(sv.cfg.BindAddr, strconv.Itoa(sv.cfg.BindPort)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -174,7 +175,7 @@ type XTCPVisitor struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (sv *XTCPVisitor) Run() (err error) {
|
func (sv *XTCPVisitor) Run() (err error) {
|
||||||
sv.l, err = net.Listen("tcp", fmt.Sprintf("%s:%d", sv.cfg.BindAddr, sv.cfg.BindPort))
|
sv.l, err = net.Listen("tcp", net.JoinHostPort(sv.cfg.BindAddr, strconv.Itoa(sv.cfg.BindPort)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -352,7 +353,7 @@ type SUDPVisitor struct {
|
|||||||
func (sv *SUDPVisitor) Run() (err error) {
|
func (sv *SUDPVisitor) Run() (err error) {
|
||||||
xl := xlog.FromContextSafe(sv.ctx)
|
xl := xlog.FromContextSafe(sv.ctx)
|
||||||
|
|
||||||
addr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", sv.cfg.BindAddr, sv.cfg.BindPort))
|
addr, err := net.ResolveUDPAddr("udp", net.JoinHostPort(sv.cfg.BindAddr, strconv.Itoa(sv.cfg.BindPort)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("sudp ResolveUDPAddr error: %v", err)
|
return fmt.Errorf("sudp ResolveUDPAddr error: %v", err)
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 41 KiB |
BIN
doc/pic/sponsor_workos.png
Normal file
BIN
doc/pic/sponsor_workos.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 37 KiB |
@ -18,6 +18,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -163,7 +164,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", net.JoinHostPort(bindAddr, strconv.Itoa(bindPort)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return l, err
|
return l, err
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,9 @@ package net
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"golang.org/x/net/websocket"
|
"golang.org/x/net/websocket"
|
||||||
)
|
)
|
||||||
@ -52,7 +52,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", net.JoinHostPort(bindAddr, strconv.Itoa(bindPort)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ func readHTTPConnectRequest(rd io.Reader) (host string, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
host = util.GetHostFromAddr(req.Host)
|
host, _ = util.CanonicalHost(req.Host)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,17 +34,6 @@ func OkResponse() *http.Response {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: use "CanonicalHost" func to replace all "GetHostFromAddr" func.
|
|
||||||
func GetHostFromAddr(addr string) (host string) {
|
|
||||||
strs := strings.Split(addr, ":")
|
|
||||||
if len(strs) > 1 {
|
|
||||||
host = strs[0]
|
|
||||||
} else {
|
|
||||||
host = addr
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// canonicalHost strips port from host if present and returns the canonicalized
|
// canonicalHost strips port from host if present and returns the canonicalized
|
||||||
// host name.
|
// host name.
|
||||||
func CanonicalHost(host string) (string, error) {
|
func CanonicalHost(host string) (string, error) {
|
||||||
|
@ -19,6 +19,7 @@ import (
|
|||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@ -52,7 +53,7 @@ func CanonicalAddr(host string, port int) (addr string) {
|
|||||||
if port == 80 || port == 443 {
|
if port == 80 || port == 443 {
|
||||||
addr = host
|
addr = host
|
||||||
} else {
|
} else {
|
||||||
addr = fmt.Sprintf("%s:%d", host, port)
|
addr = net.JoinHostPort(host, strconv.Itoa(port))
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var version string = "0.39.0"
|
var version string = "0.39.1"
|
||||||
|
|
||||||
func Full() string {
|
func Full() string {
|
||||||
return version
|
return version
|
||||||
|
@ -59,7 +59,7 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) *
|
|||||||
Director: func(req *http.Request) {
|
Director: func(req *http.Request) {
|
||||||
req.URL.Scheme = "http"
|
req.URL.Scheme = "http"
|
||||||
url := req.Context().Value(RouteInfoURL).(string)
|
url := req.Context().Value(RouteInfoURL).(string)
|
||||||
oldHost := util.GetHostFromAddr(req.Context().Value(RouteInfoHost).(string))
|
oldHost, _ := util.CanonicalHost(req.Context().Value(RouteInfoHost).(string))
|
||||||
rc := rp.GetRouteConfig(oldHost, url)
|
rc := rp.GetRouteConfig(oldHost, url)
|
||||||
if rc != nil {
|
if rc != nil {
|
||||||
if rc.RewriteHost != "" {
|
if rc.RewriteHost != "" {
|
||||||
@ -81,7 +81,7 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) *
|
|||||||
IdleConnTimeout: 60 * time.Second,
|
IdleConnTimeout: 60 * time.Second,
|
||||||
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||||
url := ctx.Value(RouteInfoURL).(string)
|
url := ctx.Value(RouteInfoURL).(string)
|
||||||
host := util.GetHostFromAddr(ctx.Value(RouteInfoHost).(string))
|
host, _ := util.CanonicalHost(ctx.Value(RouteInfoHost).(string))
|
||||||
remote := ctx.Value(RouteInfoRemote).(string)
|
remote := ctx.Value(RouteInfoRemote).(string)
|
||||||
return rp.CreateConnection(host, url, remote)
|
return rp.CreateConnection(host, url, remote)
|
||||||
},
|
},
|
||||||
@ -191,7 +191,7 @@ func (rp *HTTPReverseProxy) getVhost(domain string, location string) (vr *Router
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (rp *HTTPReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
func (rp *HTTPReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||||
domain := util.GetHostFromAddr(req.Host)
|
domain, _ := util.CanonicalHost(req.Host)
|
||||||
location := req.URL.Path
|
location := req.URL.Path
|
||||||
user, passwd, _ := req.BasicAuth()
|
user, passwd, _ := req.BasicAuth()
|
||||||
if !rp.CheckAuth(domain, location, user, passwd) {
|
if !rp.CheckAuth(domain, location, user, passwd) {
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
package group
|
package group
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net"
|
"net"
|
||||||
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/fatedier/frp/server/ports"
|
"github.com/fatedier/frp/server/ports"
|
||||||
@ -101,7 +101,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", net.JoinHostPort(addr, strconv.Itoa(port)))
|
||||||
if errRet != nil {
|
if errRet != nil {
|
||||||
err = errRet
|
err = errRet
|
||||||
return
|
return
|
||||||
|
@ -2,8 +2,8 @@ package ports
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"net"
|
"net"
|
||||||
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -134,7 +134,7 @@ func (pm *Manager) Acquire(name string, port int) (realPort int, err error) {
|
|||||||
|
|
||||||
func (pm *Manager) isPortAvailable(port int) bool {
|
func (pm *Manager) 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", net.JoinHostPort(pm.bindAddr, strconv.Itoa(port)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -146,7 +146,7 @@ func (pm *Manager) isPortAvailable(port int) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
l, err := net.Listen(pm.netType, fmt.Sprintf("%s:%d", pm.bindAddr, port))
|
l, err := net.Listen(pm.netType, net.JoinHostPort(pm.bindAddr, strconv.Itoa(port)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ package proxy
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/fatedier/frp/pkg/config"
|
"github.com/fatedier/frp/pkg/config"
|
||||||
)
|
)
|
||||||
@ -54,7 +55,7 @@ func (pxy *TCPProxy) Run() (remoteAddr string, err error) {
|
|||||||
pxy.rc.TCPPortManager.Release(pxy.realPort)
|
pxy.rc.TCPPortManager.Release(pxy.realPort)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
listener, errRet := net.Listen("tcp", fmt.Sprintf("%s:%d", pxy.serverCfg.ProxyBindAddr, pxy.realPort))
|
listener, errRet := net.Listen("tcp", net.JoinHostPort(pxy.serverCfg.ProxyBindAddr, strconv.Itoa(pxy.realPort)))
|
||||||
if errRet != nil {
|
if errRet != nil {
|
||||||
err = errRet
|
err = errRet
|
||||||
return
|
return
|
||||||
|
@ -19,6 +19,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/fatedier/frp/pkg/config"
|
"github.com/fatedier/frp/pkg/config"
|
||||||
@ -70,7 +71,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", pxy.serverCfg.ProxyBindAddr, pxy.realPort))
|
addr, errRet := net.ResolveUDPAddr("udp", net.JoinHostPort(pxy.serverCfg.ProxyBindAddr, strconv.Itoa(pxy.realPort)))
|
||||||
if errRet != nil {
|
if errRet != nil {
|
||||||
err = errRet
|
err = errRet
|
||||||
return
|
return
|
||||||
|
@ -124,7 +124,8 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) {
|
|||||||
// Create tcpmux httpconnect multiplexer.
|
// Create tcpmux httpconnect multiplexer.
|
||||||
if cfg.TCPMuxHTTPConnectPort > 0 {
|
if cfg.TCPMuxHTTPConnectPort > 0 {
|
||||||
var l net.Listener
|
var l net.Listener
|
||||||
l, err = net.Listen("tcp", fmt.Sprintf("%s:%d", cfg.ProxyBindAddr, cfg.TCPMuxHTTPConnectPort))
|
address := net.JoinHostPort(cfg.ProxyBindAddr, strconv.Itoa(cfg.TCPMuxHTTPConnectPort))
|
||||||
|
l, err = net.Listen("tcp", address)
|
||||||
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
|
||||||
@ -135,7 +136,7 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) {
|
|||||||
err = fmt.Errorf("Create vhost tcpMuxer error, %v", err)
|
err = fmt.Errorf("Create vhost tcpMuxer error, %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Info("tcpmux httpconnect multiplexer listen on %s:%d", cfg.ProxyBindAddr, cfg.TCPMuxHTTPConnectPort)
|
log.Info("tcpmux httpconnect multiplexer listen on %s", address)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init all plugins
|
// Init all plugins
|
||||||
@ -199,7 +200,7 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) {
|
|||||||
err = fmt.Errorf("Listen on kcp address udp %s error: %v", address, err)
|
err = fmt.Errorf("Listen on kcp address udp %s error: %v", address, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Info("frps kcp listen on udp %s:%d", cfg.BindAddr, cfg.KCPBindPort)
|
log.Info("frps kcp listen on udp %s", address)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listen for accepting connections from client using websocket protocol.
|
// Listen for accepting connections from client using websocket protocol.
|
||||||
@ -232,7 +233,7 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
go server.Serve(l)
|
go server.Serve(l)
|
||||||
log.Info("http service listen on %s:%d", cfg.ProxyBindAddr, cfg.VhostHTTPPort)
|
log.Info("http service listen on %s", address)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create https vhost muxer.
|
// Create https vhost muxer.
|
||||||
@ -288,7 +289,7 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) {
|
|||||||
err = fmt.Errorf("Create dashboard web server error, %v", err)
|
err = fmt.Errorf("Create dashboard web server error, %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Info("Dashboard listen on %s:%d", cfg.DashboardAddr, cfg.DashboardPort)
|
log.Info("Dashboard listen on %s", address)
|
||||||
statsEnable = true
|
statsEnable = true
|
||||||
}
|
}
|
||||||
if statsEnable {
|
if statsEnable {
|
||||||
|
@ -249,4 +249,24 @@ var _ = Describe("[Feature: Client-Server]", func() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Describe("IPv6 bind address", func() {
|
||||||
|
supportProtocols := []string{"tcp", "kcp", "websocket"}
|
||||||
|
for _, protocol := range supportProtocols {
|
||||||
|
tmp := protocol
|
||||||
|
defineClientServerTest("IPv6 bind address: "+strings.ToUpper(tmp), f, &generalTestConfigures{
|
||||||
|
server: fmt.Sprintf(`
|
||||||
|
bind_addr = ::
|
||||||
|
kcp_bind_port = {{ .%s }}
|
||||||
|
protocol = %s
|
||||||
|
`, consts.PortServerName, protocol),
|
||||||
|
client: fmt.Sprintf(`
|
||||||
|
tls_enable = true
|
||||||
|
protocol = %s
|
||||||
|
disable_custom_tls_first_byte = true
|
||||||
|
`, protocol),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
@ -2,7 +2,6 @@ package httpserver
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -97,7 +96,7 @@ func (s *Server) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) initListener() (err error) {
|
func (s *Server) initListener() (err error) {
|
||||||
s.l, err = net.Listen("tcp", fmt.Sprintf("%s:%d", s.bindAddr, s.bindPort))
|
s.l, err = net.Listen("tcp", net.JoinHostPort(s.bindAddr, strconv.Itoa(s.bindPort)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
libnet "github.com/fatedier/frp/pkg/util/net"
|
libnet "github.com/fatedier/frp/pkg/util/net"
|
||||||
"github.com/fatedier/frp/test/e2e/pkg/rpc"
|
"github.com/fatedier/frp/test/e2e/pkg/rpc"
|
||||||
@ -99,7 +100,7 @@ func (s *Server) Close() error {
|
|||||||
func (s *Server) initListener() (err error) {
|
func (s *Server) initListener() (err error) {
|
||||||
switch s.netType {
|
switch s.netType {
|
||||||
case TCP:
|
case TCP:
|
||||||
s.l, err = net.Listen("tcp", fmt.Sprintf("%s:%d", s.bindAddr, s.bindPort))
|
s.l, err = net.Listen("tcp", net.JoinHostPort(s.bindAddr, strconv.Itoa(s.bindPort)))
|
||||||
case UDP:
|
case UDP:
|
||||||
s.l, err = libnet.ListenUDP(s.bindAddr, s.bindPort)
|
s.l, err = libnet.ListenUDP(s.bindAddr, s.bindPort)
|
||||||
case Unix:
|
case Unix:
|
||||||
|
@ -3,6 +3,7 @@ package port
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
@ -57,7 +58,7 @@ func (pa *Allocator) GetByName(portName string) int {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", port))
|
l, err := net.Listen("tcp", net.JoinHostPort("127.0.0.1", strconv.Itoa(port)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Maybe not controlled by us, mark it used.
|
// Maybe not controlled by us, mark it used.
|
||||||
pa.used.Insert(port)
|
pa.used.Insert(port)
|
||||||
@ -65,7 +66,7 @@ func (pa *Allocator) GetByName(portName string) int {
|
|||||||
}
|
}
|
||||||
l.Close()
|
l.Close()
|
||||||
|
|
||||||
udpAddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("127.0.0.1:%d", port))
|
udpAddr, err := net.ResolveUDPAddr("udp", net.JoinHostPort("127.0.0.1", strconv.Itoa(port)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user