diff --git a/client/proxy/proxy.go b/client/proxy/proxy.go index 0c9ea52f..61d7d339 100644 --- a/client/proxy/proxy.go +++ b/client/proxy/proxy.go @@ -543,7 +543,7 @@ func (pxy *UdpProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) { go workConnSenderFn(pxy.workConn, pxy.sendCh) go workConnReaderFn(pxy.workConn, pxy.readCh) go heartbeatFn(pxy.workConn, pxy.sendCh) - udp.Forwarder(pxy.localAddr, pxy.readCh, pxy.sendCh) + udp.Forwarder(pxy.localAddr, pxy.readCh, pxy.sendCh, int(pxy.clientCfg.UdpPacketSize)) } type SudpProxy struct { @@ -688,7 +688,7 @@ func (pxy *SudpProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) { go workConnReaderFn(workConn, readCh) go heartbeatFn(workConn, sendCh) - udp.Forwarder(pxy.localAddr, readCh, sendCh) + udp.Forwarder(pxy.localAddr, readCh, sendCh, int(pxy.clientCfg.UdpPacketSize)) } // Common handler for tcp work connections. diff --git a/client/visitor.go b/client/visitor.go index d3004868..f5b5a151 100644 --- a/client/visitor.go +++ b/client/visitor.go @@ -369,7 +369,7 @@ func (sv *SudpVisitor) Run() (err error) { xl.Info("sudp start to work") go sv.dispatcher() - go udp.ForwardUserConn(sv.udpConn, sv.readCh, sv.sendCh) + go udp.ForwardUserConn(sv.udpConn, sv.readCh, sv.sendCh, int(sv.ctl.clientCfg.UdpPacketSize)) return } diff --git a/conf/frpc_full.ini b/conf/frpc_full.ini index 35fbb171..7aacfebf 100644 --- a/conf/frpc_full.ini +++ b/conf/frpc_full.ini @@ -68,6 +68,11 @@ tls_enable = true meta_var1 = 123 meta_var2 = 234 +# specify udp packet size, unit is byte. If not set, the default value is 1500. +# This parameter should be same between client and server. +# It affects the udp and sudp proxy. +udp_packet_size = 1500 + # 'ssh' is the unique proxy name # if user in [common] section is not empty, it will be changed to {user}.{proxy} such as 'your_name.ssh' [ssh] diff --git a/conf/frps_full.ini b/conf/frps_full.ini index 03896a2d..c0ffb76f 100644 --- a/conf/frps_full.ini +++ b/conf/frps_full.ini @@ -113,6 +113,11 @@ tcp_mux = true # custom 404 page for HTTP requests # custom_404_page = /path/to/404.html +# specify udp packet size, unit is byte. If not set, the default value is 1500. +# This parameter should be same between client and server. +# It affects the udp and sudp proxy. +udp_packet_size = 1500 + [plugin.user-manager] addr = 127.0.0.1:9000 path = /handler diff --git a/models/config/client_common.go b/models/config/client_common.go index 3f8c485d..c4c6bdfd 100644 --- a/models/config/client_common.go +++ b/models/config/client_common.go @@ -116,6 +116,9 @@ type ClientCommonConf struct { HeartBeatTimeout int64 `json:"heartbeat_timeout"` // Client meta info Metas map[string]string `json:"metas"` + // UdpPacketSize specifies the udp packet size + // By default, this value is 1500 + UdpPacketSize int64 `json:"udp_packet_size"` } // GetDefaultClientConf returns a client configuration with default values. @@ -145,6 +148,7 @@ func GetDefaultClientConf() ClientCommonConf { HeartBeatInterval: 30, HeartBeatTimeout: 90, Metas: make(map[string]string), + UdpPacketSize: 1500, } } @@ -298,6 +302,14 @@ func UnmarshalClientConfFromIni(content string) (cfg ClientCommonConf, err error cfg.Metas[strings.TrimPrefix(k, "meta_")] = v } } + if tmpStr, ok = conf.Get("common", "udp_packet_size"); ok { + if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil { + err = fmt.Errorf("Parse conf error: invalid udp_packet_size") + return + } else { + cfg.UdpPacketSize = v + } + } return } diff --git a/models/config/server_common.go b/models/config/server_common.go index a6aa969e..ae2116c2 100644 --- a/models/config/server_common.go +++ b/models/config/server_common.go @@ -145,6 +145,9 @@ type ServerCommonConf struct { UserConnTimeout int64 `json:"user_conn_timeout"` // HTTPPlugins specify the server plugins support HTTP protocol. HTTPPlugins map[string]plugin.HTTPPluginOptions `json:"http_plugins"` + // UdpPacketSize specifies the udp packet size + // By default, this value is 1500 + UdpPacketSize int64 `json:"udp_packet_size"` } // GetDefaultServerConf returns a server configuration with reasonable @@ -182,6 +185,7 @@ func GetDefaultServerConf() ServerCommonConf { UserConnTimeout: 10, Custom404Page: "", HTTPPlugins: make(map[string]plugin.HTTPPluginOptions), + UdpPacketSize: 1500, } } @@ -416,6 +420,15 @@ func UnmarshalServerConfFromIni(content string) (cfg ServerCommonConf, err error } else { cfg.TlsOnly = false } + + if tmpStr, ok = conf.Get("common", "udp_packet_size"); ok { + if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil { + err = fmt.Errorf("Parse conf error: invalid udp_packet_size") + return + } else { + cfg.UdpPacketSize = v + } + } return } diff --git a/models/proto/udp/udp.go b/models/proto/udp/udp.go index 8ae1db64..3ce592cd 100644 --- a/models/proto/udp/udp.go +++ b/models/proto/udp/udp.go @@ -39,7 +39,7 @@ func GetContent(m *msg.UdpPacket) (buf []byte, err error) { return } -func ForwardUserConn(udpConn *net.UDPConn, readCh <-chan *msg.UdpPacket, sendCh chan<- *msg.UdpPacket) { +func ForwardUserConn(udpConn *net.UDPConn, readCh <-chan *msg.UdpPacket, sendCh chan<- *msg.UdpPacket, bufSize int) { // read go func() { for udpMsg := range readCh { @@ -52,7 +52,7 @@ func ForwardUserConn(udpConn *net.UDPConn, readCh <-chan *msg.UdpPacket, sendCh }() // write - buf := pool.GetBuf(1500) + buf := pool.GetBuf(bufSize) defer pool.PutBuf(buf) for { n, remoteAddr, err := udpConn.ReadFromUDP(buf) @@ -69,7 +69,7 @@ func ForwardUserConn(udpConn *net.UDPConn, readCh <-chan *msg.UdpPacket, sendCh } } -func Forwarder(dstAddr *net.UDPAddr, readCh <-chan *msg.UdpPacket, sendCh chan<- msg.Message) { +func Forwarder(dstAddr *net.UDPAddr, readCh <-chan *msg.UdpPacket, sendCh chan<- msg.Message, bufSize int) { var ( mu sync.RWMutex ) @@ -85,7 +85,7 @@ func Forwarder(dstAddr *net.UDPAddr, readCh <-chan *msg.UdpPacket, sendCh chan<- udpConn.Close() }() - buf := pool.GetBuf(1500) + buf := pool.GetBuf(bufSize) for { udpConn.SetReadDeadline(time.Now().Add(30 * time.Second)) n, _, err := udpConn.ReadFromUDP(buf) diff --git a/server/proxy/udp.go b/server/proxy/udp.go index a0471839..4388ef4b 100644 --- a/server/proxy/udp.go +++ b/server/proxy/udp.go @@ -196,7 +196,7 @@ func (pxy *UdpProxy) Run() (remoteAddr string, err error) { // Response will be wrapped to be forwarded by work connection to server. // Close readCh and sendCh at the end. go func() { - udp.ForwardUserConn(udpConn, pxy.readCh, pxy.sendCh) + udp.ForwardUserConn(udpConn, pxy.readCh, pxy.sendCh, int(pxy.serverCfg.UdpPacketSize)) pxy.Close() }() return remoteAddr, nil