diff --git a/client/proxy/proxy.go b/client/proxy/proxy.go index ece2f935..e982c03b 100644 --- a/client/proxy/proxy.go +++ b/client/proxy/proxy.go @@ -174,6 +174,26 @@ func (pxy *BaseProxy) HandleTCPWorkConnection(workConn net.Conn, m *msg.StartWor xl.Tracef("handle tcp work connection, useEncryption: %t, useCompression: %t", baseCfg.Transport.UseEncryption, baseCfg.Transport.UseCompression) + var srcAddr, dstAddr *net.TCPAddr + if m.SrcAddr != "" && m.SrcPort != 0 { + if m.DstAddr == "" { + m.DstAddr = "127.0.0.1" + } + var err error + srcAddr, err = net.ResolveTCPAddr("tcp", net.JoinHostPort(m.SrcAddr, strconv.Itoa(int(m.SrcPort)))) + if err != nil { + xl.Warnf("resolve source address [%s] error: %v", m.SrcAddr, err) + _ = workConn.Close() + return + } + dstAddr, err = net.ResolveTCPAddr("tcp", net.JoinHostPort(m.DstAddr, strconv.Itoa(int(m.DstPort)))) + if err != nil { + xl.Warnf("resolve destination address [%s] error: %v", m.DstAddr, err) + _ = workConn.Close() + return + } + } + remote, recycleFn, err := pxy.wrapWorkConn(workConn, encKey) if err != nil { xl.Errorf("wrap work connection: %v", err) @@ -183,11 +203,6 @@ func (pxy *BaseProxy) HandleTCPWorkConnection(workConn net.Conn, m *msg.StartWor // check if we need to send proxy protocol info var connInfo plugin.ConnectionInfo if m.SrcAddr != "" && m.SrcPort != 0 { - if m.DstAddr == "" { - m.DstAddr = "127.0.0.1" - } - srcAddr, _ := net.ResolveTCPAddr("tcp", net.JoinHostPort(m.SrcAddr, strconv.Itoa(int(m.SrcPort)))) - dstAddr, _ := net.ResolveTCPAddr("tcp", net.JoinHostPort(m.DstAddr, strconv.Itoa(int(m.DstPort)))) connInfo.SrcAddr = srcAddr connInfo.DstAddr = dstAddr } diff --git a/client/proxy/proxy_test.go b/client/proxy/proxy_test.go new file mode 100644 index 00000000..c51c6997 --- /dev/null +++ b/client/proxy/proxy_test.go @@ -0,0 +1,47 @@ +// Copyright 2026 The frp Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build !frps + +package proxy + +import ( + "io" + "net" + "testing" + + "github.com/stretchr/testify/require" + + v1 "github.com/fatedier/frp/pkg/config/v1" + "github.com/fatedier/frp/pkg/msg" + "github.com/fatedier/frp/pkg/util/xlog" +) + +func TestHandleTCPWorkConnectionRejectsInvalidAddress(t *testing.T) { + workConn, peerConn := net.Pipe() + defer peerConn.Close() + + pxy := &BaseProxy{ + baseCfg: &v1.ProxyBaseConfig{}, + xl: xlog.New(), + } + pxy.HandleTCPWorkConnection(workConn, &msg.StartWorkConn{ + SrcAddr: "[", + SrcPort: 1, + }, nil) + + buffer := make([]byte, 1) + _, err := peerConn.Read(buffer) + require.ErrorIs(t, err, io.EOF) +} diff --git a/go.mod b/go.mod index c1ca1917..30c106d5 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/onsi/ginkgo/v2 v2.23.4 github.com/onsi/gomega v1.36.3 github.com/pelletier/go-toml/v2 v2.2.0 - github.com/pires/go-proxyproto v0.7.0 + github.com/pires/go-proxyproto v0.15.0 github.com/prometheus/client_golang v1.19.1 github.com/quic-go/quic-go v0.60.0 github.com/rodaine/table v1.2.0 diff --git a/go.sum b/go.sum index 81758d50..238c5ae2 100644 --- a/go.sum +++ b/go.sum @@ -78,8 +78,8 @@ github.com/onsi/gomega v1.36.3 h1:hID7cr8t3Wp26+cYnfcjR6HpJ00fdogN6dqZ1t6IylU= github.com/onsi/gomega v1.36.3/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0= github.com/pelletier/go-toml/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeBAsoHo= github.com/pelletier/go-toml/v2 v2.2.0/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= -github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs= -github.com/pires/go-proxyproto v0.7.0/go.mod h1:Vz/1JPY/OACxWGQNIRY2BeyDmpoaWmEP40O9LbuiFR4= +github.com/pires/go-proxyproto v0.15.0 h1:dTshmNbFm/D+0+sbrxUuddPOZ5Y0B7c5NhtsBkm6LqI= +github.com/pires/go-proxyproto v0.15.0/go.mod h1:OXsCrKwrK2tXS9YrI5tkHx5xaQlO8FH3lFW76orFh24= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=