Skip to content

Socks: AssociatePacketConn.WriteTo returns n with header length #83

@xchacha20-poly1305

Description

@xchacha20-poly1305

func (c *AssociatePacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
destination := M.SocksaddrFromNet(addr)
buffer := buf.NewSize(3 + M.SocksaddrSerializer.AddrPortLen(destination) + len(p))
defer buffer.Release()
common.Must(buffer.WriteZeroN(3))
err = M.SocksaddrSerializer.WriteAddrPort(buffer, destination)
if err != nil {
return
}
_, err = buffer.Write(p)
if err != nil {
return
}
return c.conn.Write(buffer.Bytes())
}

My observation is that because the buffer passed to WriteTo includes the header, the returned n (number of bytes written) reflects the total length, including this header.

I have referred to other popular SOCKS implementations, and it seems they do not include the header length in the returned n for similar operations.

https://github.com/wzshiming/socks5/blob/c06aae6747c6d36ee8c5994675d7b223cdcf6540/udp.go#L53-L71

https://github.com/txthinking/socks5/blob/4230056ae3012ccd47e9d0699fb0c47c1b924554/client.go#L131-L152

https://github.com/v2fly/v2ray-core/blob/28f558601fb8b6ab1bf4cdbdd3b8848047393e77/proxy/socks/protocol.go#L435-L448

Their n are all payload's length.

This difference in behavior leads me to wonder if this is an intended feature of the SagerNet/sing implementation, or if there's another reason for this design choice.

Could you please clarify if this behavior is by design and, if so, the rationale behind it?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions