Ground-Zerro / Phobos Public
Code Issues Pull requests Actions Releases View on GitHub ↗
1.6 KB go
/* 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)))
}