1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-09-27 22:36:12 -04:00

read original addr from x-forwarded-for header if present

This commit is contained in:
Darien Raymond 2017-12-18 20:34:00 +01:00
parent a0b2c285b2
commit 91ca88bcff
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
6 changed files with 93 additions and 13 deletions

View File

@ -0,0 +1,21 @@
package http
import (
"net/http"
"strings"
"v2ray.com/core/common/net"
)
func ParseXForwardedFor(header http.Header) []net.Address {
xff := header.Get("X-Forwarded-For")
if len(xff) == 0 {
return nil
}
list := strings.Split(xff, ",")
addrs := make([]net.Address, 0, len(list))
for _, proxy := range list {
addrs = append(addrs, net.ParseAddress(proxy))
}
return addrs
}

View File

@ -0,0 +1,20 @@
package http_test
import (
"net/http"
"testing"
. "v2ray.com/core/common/protocol/http"
. "v2ray.com/ext/assert"
)
func TestParseXForwardedFor(t *testing.T) {
assert := With(t)
header := http.Header{}
header.Add("X-Forwarded-For", "129.78.138.66, 129.78.64.103")
addrs := ParseXForwardedFor(header)
assert(len(addrs), Equals, 2)
assert(addrs[0].String(), Equals, "129.78.138.66")
assert(addrs[1].String(), Equals, "129.78.64.103")
}

View File

@ -16,15 +16,16 @@ var (
// connection is a wrapper for net.Conn over WebSocket connection.
type connection struct {
conn *websocket.Conn
reader io.Reader
conn *websocket.Conn
reader io.Reader
mergingWriter *buf.BufferedWriter
remoteAddr net.Addr
}
func newConnection(conn *websocket.Conn) *connection {
func newConnection(conn *websocket.Conn, remoteAddr net.Addr) *connection {
return &connection{
conn: conn,
conn: conn,
remoteAddr: remoteAddr,
}
}
@ -86,7 +87,7 @@ func (c *connection) LocalAddr() net.Addr {
}
func (c *connection) RemoteAddr() net.Addr {
return c.conn.RemoteAddr()
return c.remoteAddr
}
func (c *connection) SetDeadline(t time.Time) error {

View File

@ -62,5 +62,5 @@ func dialWebsocket(ctx context.Context, dest net.Destination) (net.Conn, error)
return nil, newError("failed to dial to (", uri, "): ", reason).Base(err)
}
return newConnection(conn), nil
return newConnection(conn, conn.RemoteAddr()), nil
}

View File

@ -12,6 +12,7 @@ import (
"v2ray.com/core/app/log"
"v2ray.com/core/common"
"v2ray.com/core/common/net"
http_proto "v2ray.com/core/common/protocol/http"
"v2ray.com/core/transport/internet"
v2tls "v2ray.com/core/transport/internet/tls"
)
@ -38,7 +39,13 @@ func (h *requestHandler) ServeHTTP(writer http.ResponseWriter, request *http.Req
return
}
h.ln.addConn(h.ln.ctx, newConnection(conn))
forwardedAddrs := http_proto.ParseXForwardedFor(request.Header)
remoteAddr := conn.RemoteAddr()
if len(forwardedAddrs) > 0 && forwardedAddrs[0].Family().Either(net.AddressFamilyIPv4, net.AddressFamilyIPv6) {
remoteAddr.(*net.TCPAddr).IP = forwardedAddrs[0].IP()
}
h.ln.addConn(h.ln.ctx, newConnection(conn, remoteAddr))
}
type Listener struct {

View File

@ -59,15 +59,46 @@ func Test_listenWSAndDial(t *testing.T) {
assert(err, IsNil)
assert(string(b[:n]), Equals, "Response")
assert(conn.Close(), IsNil)
<-time.After(time.Second * 15)
conn, err = Dial(ctx, net.TCPDestination(net.DomainAddress("localhost"), 13146))
assert(listen.Close(), IsNil)
}
func TestDialWithRemoteAddr(t *testing.T) {
assert := With(t)
listen, err := ListenWS(internet.ContextWithTransportSettings(context.Background(), &Config{
Path: "ws",
}), net.DomainAddress("localhost"), 13146, func(ctx context.Context, conn internet.Connection) bool {
go func(c internet.Connection) {
defer c.Close()
assert(c.RemoteAddr().String(), HasPrefix, "1.1.1.1")
var b [1024]byte
n, err := c.Read(b[:])
//assert(err, IsNil)
if err != nil {
return
}
assert(bytes.HasPrefix(b[:n], []byte("Test connection")), IsTrue)
_, err = c.Write([]byte("Response"))
assert(err, IsNil)
}(conn)
return true
})
assert(err, IsNil)
_, err = conn.Write([]byte("Test connection 3"))
ctx := internet.ContextWithTransportSettings(context.Background(), &Config{Path: "ws", Header: []*Header{{Key: "X-Forwarded-For", Value: "1.1.1.1"}}})
conn, err := Dial(ctx, net.TCPDestination(net.DomainAddress("localhost"), 13146))
assert(err, IsNil)
n, err = conn.Read(b[:])
_, err = conn.Write([]byte("Test connection 1"))
assert(err, IsNil)
var b [1024]byte
n, err := conn.Read(b[:])
assert(err, IsNil)
assert(string(b[:n]), Equals, "Response")
assert(conn.Close(), IsNil)
assert(listen.Close(), IsNil)
}