mirror of
https://github.com/v2fly/v2ray-core.git
synced 2025-01-03 07:56:42 -05:00
fix: socks4/4a client handshake (#1971)
This commit is contained in:
parent
b9a8a7e237
commit
d467eb7511
@ -146,10 +146,21 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
|
|||||||
if err := conn.SetDeadline(time.Now().Add(p.Timeouts.Handshake)); err != nil {
|
if err := conn.SetDeadline(time.Now().Add(p.Timeouts.Handshake)); err != nil {
|
||||||
newError("failed to set deadline for handshake").Base(err).WriteToLog(session.ExportIDToError(ctx))
|
newError("failed to set deadline for handshake").Base(err).WriteToLog(session.ExportIDToError(ctx))
|
||||||
}
|
}
|
||||||
udpRequest, err := ClientHandshake(request, conn, conn)
|
|
||||||
|
var udpRequest *protocol.RequestHeader
|
||||||
|
var err error
|
||||||
|
if request.Version == socks4Version {
|
||||||
|
err = ClientHandshake4(request, conn, conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return newError("failed to establish connection to server").AtWarning().Base(err)
|
return newError("failed to establish connection to server").AtWarning().Base(err)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
udpRequest, err = ClientHandshake(request, conn, conn)
|
||||||
|
if err != nil {
|
||||||
|
return newError("failed to establish connection to server").AtWarning().Base(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if udpRequest != nil {
|
if udpRequest != nil {
|
||||||
if udpRequest.Address == net.AnyIP || udpRequest.Address == net.AnyIPv6 {
|
if udpRequest.Address == net.AnyIP || udpRequest.Address == net.AnyIPv6 {
|
||||||
udpRequest.Address = dest.Address
|
udpRequest.Address = dest.Address
|
||||||
|
@ -537,3 +537,46 @@ func ClientHandshake(request *protocol.RequestHeader, reader io.Reader, writer i
|
|||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ClientHandshake4(request *protocol.RequestHeader, reader io.Reader, writer io.Writer) error {
|
||||||
|
b := buf.New()
|
||||||
|
defer b.Release()
|
||||||
|
|
||||||
|
common.Must2(b.Write([]byte{socks4Version, cmdTCPConnect}))
|
||||||
|
portBytes := b.Extend(2)
|
||||||
|
binary.BigEndian.PutUint16(portBytes, request.Port.Value())
|
||||||
|
switch request.Address.Family() {
|
||||||
|
case net.AddressFamilyIPv4:
|
||||||
|
common.Must2(b.Write(request.Address.IP()))
|
||||||
|
case net.AddressFamilyDomain:
|
||||||
|
common.Must2(b.Write([]byte{0x00, 0x00, 0x00, 0x01}))
|
||||||
|
case net.AddressFamilyIPv6:
|
||||||
|
return newError("ipv6 is not supported in socks4")
|
||||||
|
default:
|
||||||
|
panic("Unknown family type.")
|
||||||
|
}
|
||||||
|
if request.User != nil {
|
||||||
|
account := request.User.Account.(*Account)
|
||||||
|
common.Must2(b.WriteString(account.Username))
|
||||||
|
}
|
||||||
|
common.Must(b.WriteByte(0x00))
|
||||||
|
if request.Address.Family() == net.AddressFamilyDomain {
|
||||||
|
common.Must2(b.WriteString(request.Address.Domain()))
|
||||||
|
common.Must(b.WriteByte(0x00))
|
||||||
|
}
|
||||||
|
if err := buf.WriteAllBytes(writer, b.Bytes()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
b.Clear()
|
||||||
|
if _, err := b.ReadFullFrom(reader, 8); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if b.Byte(0) != 0x00 {
|
||||||
|
return newError("unexpected version of the reply code: ", b.Byte(0))
|
||||||
|
}
|
||||||
|
if b.Byte(1) != socks4RequestGranted {
|
||||||
|
return newError("server rejects request: ", b.Byte(1))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user