// File: /workspace/github_c_makefile_star2_O0/GangZhuo[P]dohclient/src/channel_tcp.c
// Function: socks5_handshake
static int socks5_handshake(channel_tcp_t* ctx, tcpreq_t* req, reqconn_t *conn)
{
	int r;
	conn_status cs = conn->conn.status;
	stream_t* s = &conn->proxy_stream;
	int rsize = stream_rsize(s);

	if (s->cap < 1024) {
		if (stream_set_cap(s, 1024)) {
			return -1;
		}
	}

	switch (cs) {
	case cs_connected:
		if (rsize == 0) {
			s->array[0] = 0x05;
			s->array[1] = 0x01;
			s->array[2] = 0x00;
			s->pos = 0;
			s->size = 3;
		}
		r = tcp_send(conn->conn.sock, s);
		if (r < 0) {
			loge("tcp_send() error\n");
			return -1;
		}
		if (stream_rsize(s) > 0) {
			conn->conn.status = cs_socks5_sending_method;
		}
		else {
			conn->conn.status = cs_socks5_waiting_method;
		}
		break;
	case cs_socks5_waiting_method:
		r = tcp_recv(conn->conn.sock, s->array, s->cap);
		if (r != 2) {
			loge("tcp_recv() error\n");
			return -1;
		}
		if (s->array[0] == 0x05 && s->array[1] == 0x00) {
			sockaddr_t *upstream = &ctx->upstreams[conn->upstream];
			s->array[0] = 0x05;
			s->array[1] = 0x01;
			s->array[2] = 0x00;
			if (upstream->addr.ss_family == AF_INET) {
				struct sockaddr_in* addr = (struct sockaddr_in*)&upstream->addr;
				int port = htons(addr->sin_port);
				s->array[3] = 0x01;
				memcpy(s->array + 4, &addr->sin_addr, 4);
				s->array[8] = (char)((port >> 8) & 0xff);
				s->array[9] = (char)((port >> 0) & 0xff);
				s->size = 10;
			}
			else {
				s->array[3] = 0x04;
				struct sockaddr_in6* addr = (struct sockaddr_in6*)&upstream->addr;
				int port = htons(addr->sin6_port);
				s->array[3] = 0x01;
				memcpy(s->array + 4, &addr->sin6_addr, 16);
				s->array[20] = (char)((port >> 8) & 0xff);
				s->array[21] = (char)((port >> 0) & 0xff);
				s->size = 22;
			}
			s->pos = 0;
			conn->conn.status = cs_socks5_sending_connect;
			r = tcp_send(conn->conn.sock, s);
			if (r < 0) {
				loge("tcp_send() error\n");
				return -1;
			}
			if (stream_rsize(s) > 0) {
				conn->conn.status = cs_socks5_sending_connect;
			}
			else {
				conn->conn.status = cs_socks5_waiting_connect;
			}
		}
		else {
			loge("no support method\n");
			return -1;
		}
		break;
	case cs_socks5_sending_connect:
		r = tcp_send(conn->conn.sock, s);
		if (r < 0) {
			loge("tcp_send() error\n");
			return -1;
		}
		if (stream_rsize(s) > 0) {
			conn->conn.status = cs_socks5_sending_connect;
		}
		else {
			conn->conn.status = cs_socks5_waiting_connect;
		}
		break;
	case cs_socks5_waiting_connect:
		r = tcp_recv(conn->conn.sock, s->array, s->cap);
		if (r <= 0) {
			loge("tcp_recv() error\n");
			return -1;
		}
		if (s->array[0] == 0x05 && s->array[1] == 0x00) {
			conn->conn.status = cs_socks5_handshaked;
			stream_free(s);
			logv("socks5 handshaked\n");
			r = 0;
			if (stream_rsize(&conn->conn.ws) > 0) {
				r = tcp_send(conn->conn.sock, &conn->conn.ws);
				if (r >= 0)
					r = 0;
			}
			return r;
		}
		else {
			loge("connect error\n");
			return -1;
		}
		break;
	default:
		loge("unknown status\n");
		return -1;
	}

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x20(%rbp), %rax
movl 0x38(%rax), %eax
movl %eax, -0x28(%rbp)
movq -0x20(%rbp), %rax
addq $0x70, %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movl 0x8(%rax), %eax
movq -0x30(%rbp), %rcx
subl 0xc(%rcx), %eax
movl %eax, -0x34(%rbp)
movq -0x30(%rbp), %rax
cmpl $0x400, 0x10(%rax)      # imm = 0x400
jge 0x16c49
movq -0x30(%rbp), %rdi
movl $0x400, %esi            # imm = 0x400
callq 0x2d900
cmpl $0x0, %eax
je 0x16c47
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1721a
jmp 0x16c49
movl -0x28(%rbp), %eax
addl $-0x2, %eax
movl %eax, %ecx
movq %rcx, -0x68(%rbp)
subl $0x6, %eax
ja 0x171d4
movq -0x68(%rbp), %rax
leaq 0x1fbab(%rip), %rcx     # 0x36814
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
cmpl $0x0, -0x34(%rbp)
jne 0x16cae
movq -0x30(%rbp), %rax
movq (%rax), %rax
movb $0x5, (%rax)
movq -0x30(%rbp), %rax
movq (%rax), %rax
movb $0x1, 0x1(%rax)
movq -0x30(%rbp), %rax
movq (%rax), %rax
movb $0x0, 0x2(%rax)
movq -0x30(%rbp), %rax
movl $0x0, 0xc(%rax)
movq -0x30(%rbp), %rax
movl $0x3, 0x8(%rax)
movq -0x20(%rbp), %rax
movl (%rax), %edi
movq -0x30(%rbp), %rsi
callq 0x265a0
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
jge 0x16d08
jmp 0x16cc8
movb $0x0, %al
callq 0x242d0
cmpl $0x3, (%rax)
jl 0x16cfa
movl $0x3, %edi
leaq 0x1fb50(%rip), %rsi     # 0x36830
leaq 0x20e79(%rip), %rdx     # 0x37b60
movl $0x1c7, %ecx            # imm = 0x1C7
leaq 0x1fbd7(%rip), %r8      # 0x368ca
movb $0x0, %al
callq 0x243b0
jmp 0x16cfc
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1721a
movq -0x30(%rbp), %rax
movl 0x8(%rax), %eax
movq -0x30(%rbp), %rcx
subl 0xc(%rcx), %eax
cmpl $0x0, %eax
jle 0x16d28
movq -0x20(%rbp), %rax
movl $0x5, 0x38(%rax)
jmp 0x16d33
movq -0x20(%rbp), %rax
movl $0x6, 0x38(%rax)
jmp 0x17213
movq -0x20(%rbp), %rax
movl (%rax), %edi
movq -0x30(%rbp), %rax
movq (%rax), %rsi
movq -0x30(%rbp), %rax
movl 0x10(%rax), %edx
callq 0x26730
movl %eax, -0x24(%rbp)
cmpl $0x2, -0x24(%rbp)
je 0x16d9c
jmp 0x16d5c
movb $0x0, %al
callq 0x242d0
cmpl $0x3, (%rax)
jl 0x16d8e
movl $0x3, %edi
leaq 0x1fabc(%rip), %rsi     # 0x36830
leaq 0x20de5(%rip), %rdx     # 0x37b60
movl $0x1d4, %ecx            # imm = 0x1D4
leaq 0x1fbc8(%rip), %r8      # 0x3694f
movb $0x0, %al
callq 0x243b0
jmp 0x16d90
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1721a
movq -0x30(%rbp), %rax
movq (%rax), %rax
movsbl (%rax), %eax
cmpl $0x5, %eax
jne 0x16fa7
movq -0x30(%rbp), %rax
movq (%rax), %rax
movsbl 0x1(%rax), %eax
cmpl $0x0, %eax
jne 0x16fa7
movq -0x10(%rbp), %rax
addq $0x70, %rax
movq -0x20(%rbp), %rcx
movslq 0x90(%rcx), %rcx
imulq $0x88, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x40(%rbp)
movq -0x30(%rbp), %rax
movq (%rax), %rax
movb $0x5, (%rax)
movq -0x30(%rbp), %rax
movq (%rax), %rax
movb $0x1, 0x1(%rax)
movq -0x30(%rbp), %rax
movq (%rax), %rax
movb $0x0, 0x2(%rax)
movq -0x40(%rbp), %rax
movzwl (%rax), %eax
cmpl $0x2, %eax
jne 0x16e85
movq -0x40(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
movzwl 0x2(%rax), %edi
callq 0x3070
movzwl %ax, %eax
movl %eax, -0x4c(%rbp)
movq -0x30(%rbp), %rax
movq (%rax), %rax
movb $0x1, 0x3(%rax)
movq -0x30(%rbp), %rax
movq (%rax), %rax
movq -0x48(%rbp), %rcx
movl 0x4(%rcx), %ecx
movl %ecx, 0x4(%rax)
movl -0x4c(%rbp), %eax
sarl $0x8, %eax
andl $0xff, %eax
movb %al, %cl
movq -0x30(%rbp), %rax
movq (%rax), %rax
movb %cl, 0x8(%rax)
movl -0x4c(%rbp), %eax
sarl $0x0, %eax
andl $0xff, %eax
movb %al, %cl
movq -0x30(%rbp), %rax
movq (%rax), %rax
movb %cl, 0x9(%rax)
movq -0x30(%rbp), %rax
movl $0xa, 0x8(%rax)
jmp 0x16f0a
movq -0x30(%rbp), %rax
movq (%rax), %rax
movb $0x4, 0x3(%rax)
movq -0x40(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movzwl 0x2(%rax), %edi
callq 0x3070
movzwl %ax, %eax
movl %eax, -0x5c(%rbp)
movq -0x30(%rbp), %rax
movq (%rax), %rax
movb $0x1, 0x3(%rax)
movq -0x30(%rbp), %rax
movq (%rax), %rax
movq -0x58(%rbp), %rcx
movq 0x8(%rcx), %rdx
movq %rdx, 0x4(%rax)
movq 0x10(%rcx), %rcx
movq %rcx, 0xc(%rax)
movl -0x5c(%rbp), %eax
sarl $0x8, %eax
andl $0xff, %eax
movb %al, %cl
movq -0x30(%rbp), %rax
movq (%rax), %rax
movb %cl, 0x14(%rax)
movl -0x5c(%rbp), %eax
sarl $0x0, %eax
andl $0xff, %eax
movb %al, %cl
movq -0x30(%rbp), %rax
movq (%rax), %rax
movb %cl, 0x15(%rax)
movq -0x30(%rbp), %rax
movl $0x16, 0x8(%rax)
movq -0x30(%rbp), %rax
movl $0x0, 0xc(%rax)
movq -0x20(%rbp), %rax
movl $0x7, 0x38(%rax)
movq -0x20(%rbp), %rax
movl (%rax), %edi
movq -0x30(%rbp), %rsi
callq 0x265a0
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
jge 0x16f7a
jmp 0x16f3a
movb $0x0, %al
callq 0x242d0
cmpl $0x3, (%rax)
jl 0x16f6c
movl $0x3, %edi
leaq 0x1f8de(%rip), %rsi     # 0x36830
leaq 0x20c07(%rip), %rdx     # 0x37b60
movl $0x1f3, %ecx            # imm = 0x1F3
leaq 0x1f965(%rip), %r8      # 0x368ca
movb $0x0, %al
callq 0x243b0
jmp 0x16f6e
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1721a
movq -0x30(%rbp), %rax
movl 0x8(%rax), %eax
movq -0x30(%rbp), %rcx
subl 0xc(%rcx), %eax
cmpl $0x0, %eax
jle 0x16f9a
movq -0x20(%rbp), %rax
movl $0x7, 0x38(%rax)
jmp 0x16fa5
movq -0x20(%rbp), %rax
movl $0x8, 0x38(%rax)
jmp 0x16fe9
jmp 0x16fa9
movb $0x0, %al
callq 0x242d0
cmpl $0x3, (%rax)
jl 0x16fdb
movl $0x3, %edi
leaq 0x1f86f(%rip), %rsi     # 0x36830
leaq 0x20b98(%rip), %rdx     # 0x37b60
movl $0x1fe, %ecx            # imm = 0x1FE
leaq 0x1f98d(%rip), %r8      # 0x36961
movb $0x0, %al
callq 0x243b0
jmp 0x16fdd
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1721a
jmp 0x17213
movq -0x20(%rbp), %rax
movl (%rax), %edi
movq -0x30(%rbp), %rsi
callq 0x265a0
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
jge 0x17048
jmp 0x17008
movb $0x0, %al
callq 0x242d0
cmpl $0x3, (%rax)
jl 0x1703a
movl $0x3, %edi
leaq 0x1f810(%rip), %rsi     # 0x36830
leaq 0x20b39(%rip), %rdx     # 0x37b60
movl $0x205, %ecx            # imm = 0x205
leaq 0x1f897(%rip), %r8      # 0x368ca
movb $0x0, %al
callq 0x243b0
jmp 0x1703c
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1721a
movq -0x30(%rbp), %rax
movl 0x8(%rax), %eax
movq -0x30(%rbp), %rcx
subl 0xc(%rcx), %eax
cmpl $0x0, %eax
jle 0x17068
movq -0x20(%rbp), %rax
movl $0x7, 0x38(%rax)
jmp 0x17073
movq -0x20(%rbp), %rax
movl $0x8, 0x38(%rax)
jmp 0x17213
movq -0x20(%rbp), %rax
movl (%rax), %edi
movq -0x30(%rbp), %rax
movq (%rax), %rsi
movq -0x30(%rbp), %rax
movl 0x10(%rax), %edx
callq 0x26730
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
jg 0x170dc
jmp 0x1709c
movb $0x0, %al
callq 0x242d0
cmpl $0x3, (%rax)
jl 0x170ce
movl $0x3, %edi
leaq 0x1f77c(%rip), %rsi     # 0x36830
leaq 0x20aa5(%rip), %rdx     # 0x37b60
movl $0x212, %ecx            # imm = 0x212
leaq 0x1f888(%rip), %r8      # 0x3694f
movb $0x0, %al
callq 0x243b0
jmp 0x170d0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1721a
movq -0x30(%rbp), %rax
movq (%rax), %rax
movsbl (%rax), %eax
cmpl $0x5, %eax
jne 0x17195
movq -0x30(%rbp), %rax
movq (%rax), %rax
movsbl 0x1(%rax), %eax
cmpl $0x0, %eax
jne 0x17195
movq -0x20(%rbp), %rax
movl $0x9, 0x38(%rax)
movq -0x30(%rbp), %rdi
callq 0x2d640
movb $0x0, %al
callq 0x242d0
cmpl $0x8, (%rax)
jl 0x17149
movl $0x8, %edi
leaq 0x1f701(%rip), %rsi     # 0x36830
leaq 0x20a2a(%rip), %rdx     # 0x37b60
movl $0x218, %ecx            # imm = 0x218
leaq 0x1f832(%rip), %r8      # 0x36974
movb $0x0, %al
callq 0x243b0
jmp 0x1714b
movl $0x0, -0x24(%rbp)
movq -0x20(%rbp), %rax
movl 0x28(%rax), %eax
movq -0x20(%rbp), %rcx
subl 0x2c(%rcx), %eax
cmpl $0x0, %eax
jle 0x1718a
movq -0x20(%rbp), %rax
movl (%rax), %edi
movq -0x20(%rbp), %rsi
addq $0x20, %rsi
callq 0x265a0
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
jl 0x17188
movl $0x0, -0x24(%rbp)
jmp 0x1718a
movl -0x24(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x1721a
jmp 0x17197
movb $0x0, %al
callq 0x242d0
cmpl $0x3, (%rax)
jl 0x171c9
movl $0x3, %edi
leaq 0x1f681(%rip), %rsi     # 0x36830
leaq 0x209aa(%rip), %rdx     # 0x37b60
movl $0x222, %ecx            # imm = 0x222
leaq 0x1f7c5(%rip), %r8      # 0x36987
movb $0x0, %al
callq 0x243b0
jmp 0x171cb
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1721a
jmp 0x171d6
movb $0x0, %al
callq 0x242d0
cmpl $0x3, (%rax)
jl 0x17208
movl $0x3, %edi
leaq 0x1f642(%rip), %rsi     # 0x36830
leaq 0x2096b(%rip), %rdx     # 0x37b60
movl $0x227, %ecx            # imm = 0x227
leaq 0x1f795(%rip), %r8      # 0x36996
movb $0x0, %al
callq 0x243b0
jmp 0x1720a
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1721a
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x70, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)