/* SPDX-License-Identifier: MIT * * Phobos */ package cobf /* #cgo CFLAGS: -I${SRCDIR}/../../../src/phobos-obfuscator #include "bridge.h" */ import "C" import "unsafe" // MaxTargetSize is the largest SOCKS5 address block: ATYP, domain length, // a 255-byte domain and the port. const MaxTargetSize = 1 + 1 + 255 + 2 // ParseTarget decodes the ATYP/address/port block at the start of buf. // consumed > 0 is the number of bytes read; consumed == 0 means buf is still // incomplete; consumed < 0 means the address type is not supported. addr // aliases buf rather than copying: the block always ends with the two port // bytes, so its position follows from consumed and the address length. func ParseTarget(buf []byte) (atyp byte, addr []byte, port uint16, consumed int) { if len(buf) == 0 { return 0, nil, 0, 0 } var ( cAtyp C.uint8_t cAddrLen C.int cPort C.uint16_t ) consumed = int(C.cobf_parse_target((*C.uint8_t)(unsafe.SliceData(buf)), C.int(len(buf)), &cAtyp, &cAddrLen, &cPort)) if consumed <= 0 { return 0, nil, 0, consumed } end := consumed - 2 return byte(cAtyp), buf[end-int(cAddrLen) : end], uint16(cPort), consumed } // BuildTarget writes the ATYP/address/port block into out and returns its // length, or -1 when out is too small. It never allocates. func BuildTarget(out []byte, atyp byte, addr []byte, port uint16) int { if len(out) == 0 { return -1 } var addrPtr *C.uint8_t if len(addr) > 0 { addrPtr = (*C.uint8_t)(unsafe.SliceData(addr)) } return int(C.cobf_build_target((*C.uint8_t)(unsafe.SliceData(out)), C.int(len(out)), C.uint8_t(atyp), addrPtr, C.int(len(addr)), C.uint16_t(port))) }