github.com/sagernet/sing-box@v1.9.0-rc.20/transport/vless/client.go (about) 1 package vless 2 3 import ( 4 "encoding/binary" 5 "io" 6 "net" 7 "sync" 8 9 "github.com/sagernet/sing-vmess" 10 "github.com/sagernet/sing/common" 11 "github.com/sagernet/sing/common/buf" 12 "github.com/sagernet/sing/common/bufio" 13 E "github.com/sagernet/sing/common/exceptions" 14 "github.com/sagernet/sing/common/logger" 15 M "github.com/sagernet/sing/common/metadata" 16 N "github.com/sagernet/sing/common/network" 17 18 "github.com/gofrs/uuid/v5" 19 ) 20 21 type Client struct { 22 key [16]byte 23 flow string 24 logger logger.Logger 25 } 26 27 func NewClient(userId string, flow string, logger logger.Logger) (*Client, error) { 28 user := uuid.FromStringOrNil(userId) 29 if user == uuid.Nil { 30 user = uuid.NewV5(user, userId) 31 } 32 switch flow { 33 case "", "xtls-rprx-vision": 34 default: 35 return nil, E.New("unsupported flow: " + flow) 36 } 37 return &Client{user, flow, logger}, nil 38 } 39 40 func (c *Client) prepareConn(conn net.Conn, tlsConn net.Conn) (net.Conn, error) { 41 if c.flow == FlowVision { 42 protocolConn, err := NewVisionConn(conn, tlsConn, c.key, c.logger) 43 if err != nil { 44 return nil, E.Cause(err, "initialize vision") 45 } 46 conn = protocolConn 47 } 48 return conn, nil 49 } 50 51 func (c *Client) DialConn(conn net.Conn, destination M.Socksaddr) (net.Conn, error) { 52 remoteConn := NewConn(conn, c.key, vmess.CommandTCP, destination, c.flow) 53 protocolConn, err := c.prepareConn(remoteConn, conn) 54 if err != nil { 55 return nil, err 56 } 57 return protocolConn, common.Error(remoteConn.Write(nil)) 58 } 59 60 func (c *Client) DialEarlyConn(conn net.Conn, destination M.Socksaddr) (net.Conn, error) { 61 return c.prepareConn(NewConn(conn, c.key, vmess.CommandTCP, destination, c.flow), conn) 62 } 63 64 func (c *Client) DialPacketConn(conn net.Conn, destination M.Socksaddr) (*PacketConn, error) { 65 serverConn := &PacketConn{Conn: conn, key: c.key, destination: destination, flow: c.flow} 66 return serverConn, common.Error(serverConn.Write(nil)) 67 } 68 69 func (c *Client) DialEarlyPacketConn(conn net.Conn, destination M.Socksaddr) (*PacketConn, error) { 70 return &PacketConn{Conn: conn, key: c.key, destination: destination, flow: c.flow}, nil 71 } 72 73 func (c *Client) DialXUDPPacketConn(conn net.Conn, destination M.Socksaddr) (vmess.PacketConn, error) { 74 remoteConn := NewConn(conn, c.key, vmess.CommandTCP, destination, c.flow) 75 protocolConn, err := c.prepareConn(remoteConn, conn) 76 if err != nil { 77 return nil, err 78 } 79 return vmess.NewXUDPConn(protocolConn, destination), common.Error(remoteConn.Write(nil)) 80 } 81 82 func (c *Client) DialEarlyXUDPPacketConn(conn net.Conn, destination M.Socksaddr) (vmess.PacketConn, error) { 83 remoteConn := NewConn(conn, c.key, vmess.CommandMux, destination, c.flow) 84 protocolConn, err := c.prepareConn(remoteConn, conn) 85 if err != nil { 86 return nil, err 87 } 88 return vmess.NewXUDPConn(protocolConn, destination), common.Error(remoteConn.Write(nil)) 89 } 90 91 var ( 92 _ N.EarlyConn = (*Conn)(nil) 93 _ N.VectorisedWriter = (*Conn)(nil) 94 ) 95 96 type Conn struct { 97 N.ExtendedConn 98 writer N.VectorisedWriter 99 request Request 100 requestWritten bool 101 responseRead bool 102 } 103 104 func NewConn(conn net.Conn, uuid [16]byte, command byte, destination M.Socksaddr, flow string) *Conn { 105 return &Conn{ 106 ExtendedConn: bufio.NewExtendedConn(conn), 107 writer: bufio.NewVectorisedWriter(conn), 108 request: Request{ 109 UUID: uuid, 110 Command: command, 111 Destination: destination, 112 Flow: flow, 113 }, 114 } 115 } 116 117 func (c *Conn) Read(b []byte) (n int, err error) { 118 if !c.responseRead { 119 err = ReadResponse(c.ExtendedConn) 120 if err != nil { 121 return 122 } 123 c.responseRead = true 124 } 125 return c.ExtendedConn.Read(b) 126 } 127 128 func (c *Conn) ReadBuffer(buffer *buf.Buffer) error { 129 if !c.responseRead { 130 err := ReadResponse(c.ExtendedConn) 131 if err != nil { 132 return err 133 } 134 c.responseRead = true 135 } 136 return c.ExtendedConn.ReadBuffer(buffer) 137 } 138 139 func (c *Conn) Write(b []byte) (n int, err error) { 140 if !c.requestWritten { 141 err = WriteRequest(c.ExtendedConn, c.request, b) 142 if err == nil { 143 n = len(b) 144 } 145 c.requestWritten = true 146 return 147 } 148 return c.ExtendedConn.Write(b) 149 } 150 151 func (c *Conn) WriteBuffer(buffer *buf.Buffer) error { 152 if !c.requestWritten { 153 err := EncodeRequest(c.request, buf.With(buffer.ExtendHeader(RequestLen(c.request)))) 154 if err != nil { 155 return err 156 } 157 c.requestWritten = true 158 } 159 return c.ExtendedConn.WriteBuffer(buffer) 160 } 161 162 func (c *Conn) WriteVectorised(buffers []*buf.Buffer) error { 163 if !c.requestWritten { 164 buffer := buf.NewSize(RequestLen(c.request)) 165 err := EncodeRequest(c.request, buffer) 166 if err != nil { 167 buffer.Release() 168 return err 169 } 170 c.requestWritten = true 171 return c.writer.WriteVectorised(append([]*buf.Buffer{buffer}, buffers...)) 172 } 173 return c.writer.WriteVectorised(buffers) 174 } 175 176 func (c *Conn) ReaderReplaceable() bool { 177 return c.responseRead 178 } 179 180 func (c *Conn) WriterReplaceable() bool { 181 return c.requestWritten 182 } 183 184 func (c *Conn) NeedHandshake() bool { 185 return !c.requestWritten 186 } 187 188 func (c *Conn) FrontHeadroom() int { 189 if c.requestWritten { 190 return 0 191 } 192 return RequestLen(c.request) 193 } 194 195 func (c *Conn) Upstream() any { 196 return c.ExtendedConn 197 } 198 199 type PacketConn struct { 200 net.Conn 201 access sync.Mutex 202 key [16]byte 203 destination M.Socksaddr 204 flow string 205 requestWritten bool 206 responseRead bool 207 } 208 209 func (c *PacketConn) Read(b []byte) (n int, err error) { 210 if !c.responseRead { 211 err = ReadResponse(c.Conn) 212 if err != nil { 213 return 214 } 215 c.responseRead = true 216 } 217 var length uint16 218 err = binary.Read(c.Conn, binary.BigEndian, &length) 219 if err != nil { 220 return 221 } 222 if cap(b) < int(length) { 223 return 0, io.ErrShortBuffer 224 } 225 return io.ReadFull(c.Conn, b[:length]) 226 } 227 228 func (c *PacketConn) Write(b []byte) (n int, err error) { 229 if !c.requestWritten { 230 c.access.Lock() 231 if c.requestWritten { 232 c.access.Unlock() 233 } else { 234 err = WritePacketRequest(c.Conn, Request{c.key, vmess.CommandUDP, c.destination, c.flow}, nil) 235 if err == nil { 236 n = len(b) 237 } 238 c.requestWritten = true 239 c.access.Unlock() 240 } 241 } 242 err = binary.Write(c.Conn, binary.BigEndian, uint16(len(b))) 243 if err != nil { 244 return 245 } 246 return c.Conn.Write(b) 247 } 248 249 func (c *PacketConn) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error { 250 defer buffer.Release() 251 dataLen := buffer.Len() 252 binary.BigEndian.PutUint16(buffer.ExtendHeader(2), uint16(dataLen)) 253 if !c.requestWritten { 254 c.access.Lock() 255 if c.requestWritten { 256 c.access.Unlock() 257 } else { 258 err := WritePacketRequest(c.Conn, Request{c.key, vmess.CommandUDP, c.destination, c.flow}, buffer.Bytes()) 259 c.requestWritten = true 260 c.access.Unlock() 261 return err 262 } 263 } 264 return common.Error(c.Conn.Write(buffer.Bytes())) 265 } 266 267 func (c *PacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) { 268 n, err = c.Read(p) 269 if err != nil { 270 return 271 } 272 if c.destination.IsFqdn() { 273 addr = c.destination 274 } else { 275 addr = c.destination.UDPAddr() 276 } 277 return 278 } 279 280 func (c *PacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) { 281 return c.Write(p) 282 } 283 284 func (c *PacketConn) FrontHeadroom() int { 285 return 2 286 } 287 288 func (c *PacketConn) NeedAdditionalReadDeadline() bool { 289 return true 290 } 291 292 func (c *PacketConn) Upstream() any { 293 return c.Conn 294 }