github.com/metacubex/mihomo@v1.18.5/transport/tuic/v4/protocol.go (about) 1 package v4 2 3 import ( 4 "encoding/binary" 5 "fmt" 6 "io" 7 "net" 8 "net/netip" 9 "strconv" 10 11 "github.com/metacubex/quic-go" 12 "lukechampine.com/blake3" 13 14 C "github.com/metacubex/mihomo/constant" 15 "github.com/metacubex/mihomo/transport/socks5" 16 ) 17 18 type BufferedReader interface { 19 io.Reader 20 io.ByteReader 21 } 22 23 type BufferedWriter interface { 24 io.Writer 25 io.ByteWriter 26 } 27 28 type CommandType byte 29 30 const ( 31 AuthenticateType = CommandType(0x00) 32 ConnectType = CommandType(0x01) 33 PacketType = CommandType(0x02) 34 DissociateType = CommandType(0x03) 35 HeartbeatType = CommandType(0x04) 36 ResponseType = CommandType(0xff) 37 ) 38 39 const VER byte = 0x04 40 41 func (c CommandType) String() string { 42 switch c { 43 case AuthenticateType: 44 return "Authenticate" 45 case ConnectType: 46 return "Connect" 47 case PacketType: 48 return "Packet" 49 case DissociateType: 50 return "Dissociate" 51 case HeartbeatType: 52 return "Heartbeat" 53 case ResponseType: 54 return "Response" 55 default: 56 return fmt.Sprintf("UnknowCommand: %#x", byte(c)) 57 } 58 } 59 60 func (c CommandType) BytesLen() int { 61 return 1 62 } 63 64 type CommandHead struct { 65 VER byte 66 TYPE CommandType 67 } 68 69 func NewCommandHead(TYPE CommandType) CommandHead { 70 return CommandHead{ 71 VER: VER, 72 TYPE: TYPE, 73 } 74 } 75 76 func ReadCommandHead(reader BufferedReader) (c CommandHead, err error) { 77 c.VER, err = reader.ReadByte() 78 if err != nil { 79 return 80 } 81 TYPE, err := reader.ReadByte() 82 if err != nil { 83 return 84 } 85 c.TYPE = CommandType(TYPE) 86 return 87 } 88 89 func (c CommandHead) WriteTo(writer BufferedWriter) (err error) { 90 err = writer.WriteByte(c.VER) 91 if err != nil { 92 return 93 } 94 err = writer.WriteByte(byte(c.TYPE)) 95 if err != nil { 96 return 97 } 98 return 99 } 100 101 func (c CommandHead) BytesLen() int { 102 return 1 + c.TYPE.BytesLen() 103 } 104 105 type Authenticate struct { 106 CommandHead 107 TKN [32]byte 108 } 109 110 func NewAuthenticate(TKN [32]byte) Authenticate { 111 return Authenticate{ 112 CommandHead: NewCommandHead(AuthenticateType), 113 TKN: TKN, 114 } 115 } 116 117 func ReadAuthenticateWithHead(head CommandHead, reader BufferedReader) (c Authenticate, err error) { 118 c.CommandHead = head 119 if c.CommandHead.TYPE != AuthenticateType { 120 err = fmt.Errorf("error command type: %s", c.CommandHead.TYPE) 121 return 122 } 123 _, err = io.ReadFull(reader, c.TKN[:]) 124 if err != nil { 125 return 126 } 127 return 128 } 129 130 func ReadAuthenticate(reader BufferedReader) (c Authenticate, err error) { 131 head, err := ReadCommandHead(reader) 132 if err != nil { 133 return 134 } 135 return ReadAuthenticateWithHead(head, reader) 136 } 137 138 func GenTKN(token string) [32]byte { 139 return blake3.Sum256([]byte(token)) 140 } 141 142 func (c Authenticate) WriteTo(writer BufferedWriter) (err error) { 143 err = c.CommandHead.WriteTo(writer) 144 if err != nil { 145 return 146 } 147 _, err = writer.Write(c.TKN[:]) 148 if err != nil { 149 return 150 } 151 return 152 } 153 154 func (c Authenticate) BytesLen() int { 155 return c.CommandHead.BytesLen() + 32 156 } 157 158 type Connect struct { 159 CommandHead 160 ADDR Address 161 } 162 163 func NewConnect(ADDR Address) Connect { 164 return Connect{ 165 CommandHead: NewCommandHead(ConnectType), 166 ADDR: ADDR, 167 } 168 } 169 170 func ReadConnectWithHead(head CommandHead, reader BufferedReader) (c Connect, err error) { 171 c.CommandHead = head 172 if c.CommandHead.TYPE != ConnectType { 173 err = fmt.Errorf("error command type: %s", c.CommandHead.TYPE) 174 return 175 } 176 c.ADDR, err = ReadAddress(reader) 177 if err != nil { 178 return 179 } 180 return 181 } 182 183 func ReadConnect(reader BufferedReader) (c Connect, err error) { 184 head, err := ReadCommandHead(reader) 185 if err != nil { 186 return 187 } 188 return ReadConnectWithHead(head, reader) 189 } 190 191 func (c Connect) WriteTo(writer BufferedWriter) (err error) { 192 err = c.CommandHead.WriteTo(writer) 193 if err != nil { 194 return 195 } 196 err = c.ADDR.WriteTo(writer) 197 if err != nil { 198 return 199 } 200 return 201 } 202 203 func (c Connect) BytesLen() int { 204 return c.CommandHead.BytesLen() + c.ADDR.BytesLen() 205 } 206 207 type Packet struct { 208 CommandHead 209 ASSOC_ID uint32 210 LEN uint16 211 ADDR Address 212 DATA []byte 213 } 214 215 func NewPacket(ASSOC_ID uint32, LEN uint16, ADDR Address, DATA []byte) Packet { 216 return Packet{ 217 CommandHead: NewCommandHead(PacketType), 218 ASSOC_ID: ASSOC_ID, 219 LEN: LEN, 220 ADDR: ADDR, 221 DATA: DATA, 222 } 223 } 224 225 func ReadPacketWithHead(head CommandHead, reader BufferedReader) (c Packet, err error) { 226 c.CommandHead = head 227 if c.CommandHead.TYPE != PacketType { 228 err = fmt.Errorf("error command type: %s", c.CommandHead.TYPE) 229 return 230 } 231 err = binary.Read(reader, binary.BigEndian, &c.ASSOC_ID) 232 if err != nil { 233 return 234 } 235 err = binary.Read(reader, binary.BigEndian, &c.LEN) 236 if err != nil { 237 return 238 } 239 c.ADDR, err = ReadAddress(reader) 240 if err != nil { 241 return 242 } 243 c.DATA = make([]byte, c.LEN) 244 _, err = io.ReadFull(reader, c.DATA) 245 if err != nil { 246 return 247 } 248 return 249 } 250 251 func ReadPacket(reader BufferedReader) (c Packet, err error) { 252 head, err := ReadCommandHead(reader) 253 if err != nil { 254 return 255 } 256 return ReadPacketWithHead(head, reader) 257 } 258 259 func (c Packet) WriteTo(writer BufferedWriter) (err error) { 260 err = c.CommandHead.WriteTo(writer) 261 if err != nil { 262 return 263 } 264 err = binary.Write(writer, binary.BigEndian, c.ASSOC_ID) 265 if err != nil { 266 return 267 } 268 err = binary.Write(writer, binary.BigEndian, c.LEN) 269 if err != nil { 270 return 271 } 272 err = c.ADDR.WriteTo(writer) 273 if err != nil { 274 return 275 } 276 _, err = writer.Write(c.DATA) 277 if err != nil { 278 return 279 } 280 return 281 } 282 283 func (c Packet) BytesLen() int { 284 return c.CommandHead.BytesLen() + 4 + 2 + c.ADDR.BytesLen() + len(c.DATA) 285 } 286 287 var PacketOverHead = NewPacket(0, 0, NewAddressAddrPort(netip.AddrPortFrom(netip.IPv6Unspecified(), 0)), nil).BytesLen() 288 289 type Dissociate struct { 290 CommandHead 291 ASSOC_ID uint32 292 } 293 294 func NewDissociate(ASSOC_ID uint32) Dissociate { 295 return Dissociate{ 296 CommandHead: NewCommandHead(DissociateType), 297 ASSOC_ID: ASSOC_ID, 298 } 299 } 300 301 func ReadDissociateWithHead(head CommandHead, reader BufferedReader) (c Dissociate, err error) { 302 c.CommandHead = head 303 if c.CommandHead.TYPE != DissociateType { 304 err = fmt.Errorf("error command type: %s", c.CommandHead.TYPE) 305 return 306 } 307 err = binary.Read(reader, binary.BigEndian, &c.ASSOC_ID) 308 if err != nil { 309 return 310 } 311 return 312 } 313 314 func ReadDissociate(reader BufferedReader) (c Dissociate, err error) { 315 head, err := ReadCommandHead(reader) 316 if err != nil { 317 return 318 } 319 return ReadDissociateWithHead(head, reader) 320 } 321 322 func (c Dissociate) WriteTo(writer BufferedWriter) (err error) { 323 err = c.CommandHead.WriteTo(writer) 324 if err != nil { 325 return 326 } 327 err = binary.Write(writer, binary.BigEndian, c.ASSOC_ID) 328 if err != nil { 329 return 330 } 331 return 332 } 333 334 func (c Dissociate) BytesLen() int { 335 return c.CommandHead.BytesLen() + 4 336 } 337 338 type Heartbeat struct { 339 CommandHead 340 } 341 342 func NewHeartbeat() Heartbeat { 343 return Heartbeat{ 344 CommandHead: NewCommandHead(HeartbeatType), 345 } 346 } 347 348 func ReadHeartbeatWithHead(head CommandHead, reader BufferedReader) (c Heartbeat, err error) { 349 c.CommandHead = head 350 if c.CommandHead.TYPE != HeartbeatType { 351 err = fmt.Errorf("error command type: %s", c.CommandHead.TYPE) 352 return 353 } 354 return 355 } 356 357 func ReadHeartbeat(reader BufferedReader) (c Heartbeat, err error) { 358 head, err := ReadCommandHead(reader) 359 if err != nil { 360 return 361 } 362 return ReadHeartbeatWithHead(head, reader) 363 } 364 365 type Response struct { 366 CommandHead 367 REP byte 368 } 369 370 func NewResponse(REP byte) Response { 371 return Response{ 372 CommandHead: NewCommandHead(ResponseType), 373 REP: REP, 374 } 375 } 376 377 func NewResponseSucceed() Response { 378 return NewResponse(0x00) 379 } 380 381 func NewResponseFailed() Response { 382 return NewResponse(0xff) 383 } 384 385 func ReadResponseWithHead(head CommandHead, reader BufferedReader) (c Response, err error) { 386 c.CommandHead = head 387 if c.CommandHead.TYPE != ResponseType { 388 err = fmt.Errorf("error command type: %s", c.CommandHead.TYPE) 389 return 390 } 391 c.REP, err = reader.ReadByte() 392 if err != nil { 393 return 394 } 395 return 396 } 397 398 func ReadResponse(reader BufferedReader) (c Response, err error) { 399 head, err := ReadCommandHead(reader) 400 if err != nil { 401 return 402 } 403 return ReadResponseWithHead(head, reader) 404 } 405 406 func (c Response) WriteTo(writer BufferedWriter) (err error) { 407 err = c.CommandHead.WriteTo(writer) 408 if err != nil { 409 return 410 } 411 err = writer.WriteByte(c.REP) 412 if err != nil { 413 return 414 } 415 return 416 } 417 418 func (c Response) IsSucceed() bool { 419 return c.REP == 0x00 420 } 421 422 func (c Response) IsFailed() bool { 423 return c.REP == 0xff 424 } 425 426 func (c Response) BytesLen() int { 427 return c.CommandHead.BytesLen() + 1 428 } 429 430 // Addr types 431 const ( 432 AtypDomainName byte = 0 433 AtypIPv4 byte = 1 434 AtypIPv6 byte = 2 435 ) 436 437 type Address struct { 438 TYPE byte 439 ADDR []byte 440 PORT uint16 441 } 442 443 func NewAddress(metadata *C.Metadata) Address { 444 var addrType byte 445 var addr []byte 446 switch metadata.AddrType() { 447 case socks5.AtypIPv4: 448 addrType = AtypIPv4 449 addr = metadata.DstIP.AsSlice() 450 case socks5.AtypIPv6: 451 addrType = AtypIPv6 452 addr = metadata.DstIP.AsSlice() 453 case socks5.AtypDomainName: 454 addrType = AtypDomainName 455 addr = make([]byte, len(metadata.Host)+1) 456 addr[0] = byte(len(metadata.Host)) 457 copy(addr[1:], metadata.Host) 458 } 459 460 return Address{ 461 TYPE: addrType, 462 ADDR: addr, 463 PORT: metadata.DstPort, 464 } 465 } 466 467 func NewAddressNetAddr(addr net.Addr) (Address, error) { 468 if addr, ok := addr.(interface{ AddrPort() netip.AddrPort }); ok { 469 if addrPort := addr.AddrPort(); addrPort.IsValid() { // sing's M.Socksaddr maybe return an invalid AddrPort if it's a DomainName 470 return NewAddressAddrPort(addrPort), nil 471 } 472 } 473 addrStr := addr.String() 474 if addrPort, err := netip.ParseAddrPort(addrStr); err == nil { 475 return NewAddressAddrPort(addrPort), nil 476 } 477 metadata := &C.Metadata{} 478 if err := metadata.SetRemoteAddress(addrStr); err != nil { 479 return Address{}, err 480 } 481 return NewAddress(metadata), nil 482 } 483 484 func NewAddressAddrPort(addrPort netip.AddrPort) Address { 485 var addrType byte 486 port := addrPort.Port() 487 addr := addrPort.Addr().Unmap() 488 if addr.Is4() { 489 addrType = AtypIPv4 490 } else { 491 addrType = AtypIPv6 492 } 493 return Address{ 494 TYPE: addrType, 495 ADDR: addr.AsSlice(), 496 PORT: port, 497 } 498 } 499 500 func ReadAddress(reader BufferedReader) (c Address, err error) { 501 c.TYPE, err = reader.ReadByte() 502 if err != nil { 503 return 504 } 505 switch c.TYPE { 506 case AtypIPv4: 507 c.ADDR = make([]byte, net.IPv4len) 508 _, err = io.ReadFull(reader, c.ADDR) 509 if err != nil { 510 return 511 } 512 case AtypIPv6: 513 c.ADDR = make([]byte, net.IPv6len) 514 _, err = io.ReadFull(reader, c.ADDR) 515 if err != nil { 516 return 517 } 518 case AtypDomainName: 519 var addrLen byte 520 addrLen, err = reader.ReadByte() 521 if err != nil { 522 return 523 } 524 c.ADDR = make([]byte, addrLen+1) 525 c.ADDR[0] = addrLen 526 _, err = io.ReadFull(reader, c.ADDR[1:]) 527 if err != nil { 528 return 529 } 530 } 531 532 err = binary.Read(reader, binary.BigEndian, &c.PORT) 533 if err != nil { 534 return 535 } 536 return 537 } 538 539 func (c Address) WriteTo(writer BufferedWriter) (err error) { 540 err = writer.WriteByte(c.TYPE) 541 if err != nil { 542 return 543 } 544 _, err = writer.Write(c.ADDR[:]) 545 if err != nil { 546 return 547 } 548 err = binary.Write(writer, binary.BigEndian, c.PORT) 549 if err != nil { 550 return 551 } 552 return 553 } 554 555 func (c Address) String() string { 556 switch c.TYPE { 557 case AtypDomainName: 558 return net.JoinHostPort(string(c.ADDR[1:]), strconv.Itoa(int(c.PORT))) 559 default: 560 addr, _ := netip.AddrFromSlice(c.ADDR) 561 addrPort := netip.AddrPortFrom(addr, c.PORT) 562 return addrPort.String() 563 } 564 } 565 566 func (c Address) SocksAddr() socks5.Addr { 567 addr := make([]byte, 1+len(c.ADDR)+2) 568 switch c.TYPE { 569 case AtypIPv4: 570 addr[0] = socks5.AtypIPv4 571 case AtypIPv6: 572 addr[0] = socks5.AtypIPv6 573 case AtypDomainName: 574 addr[0] = socks5.AtypDomainName 575 } 576 copy(addr[1:], c.ADDR) 577 binary.BigEndian.PutUint16(addr[len(addr)-2:], c.PORT) 578 return addr 579 } 580 581 func (c Address) UDPAddr() *net.UDPAddr { 582 return &net.UDPAddr{ 583 IP: c.ADDR, 584 Port: int(c.PORT), 585 Zone: "", 586 } 587 } 588 589 func (c Address) BytesLen() int { 590 return 1 + len(c.ADDR) + 2 591 } 592 593 const ( 594 ProtocolError = quic.ApplicationErrorCode(0xfffffff0) 595 AuthenticationFailed = quic.ApplicationErrorCode(0xfffffff1) 596 AuthenticationTimeout = quic.ApplicationErrorCode(0xfffffff2) 597 BadCommand = quic.ApplicationErrorCode(0xfffffff3) 598 )