// File: /workspace/github_c_makefile_star2_O0/wahern[P]cqueues/src/lib/socket.c
// Function: so_starttls_
static int so_starttls_(struct socket *so) {
	X509 *peer;
	int rval, error;

	if (so->ssl.error)
		return so->ssl.error;

	so_pipeign(so, 0);

	ERR_clear_error();

	switch (so->ssl.state) {
	case 0: {
		/*
		 * NOTE: For SOCK_DGRAM continue using OpenSSL's BIO until
		 * we have time to reverse engineer the semantics necessary
		 * for DTLS.
		 */
		if (S_ISSOCK(so->mode) && so->type == SOCK_DGRAM) {
			struct sockaddr_storage peer;
			BIO *bio;

			memset(&peer, 0, sizeof peer);

			if (0 != getpeername(so->fd, (struct sockaddr *)&peer, &(socklen_t){ sizeof peer })) {
				error = errno;
				goto error;
			}

			if (!(bio = BIO_new_dgram(so->fd, BIO_NOCLOSE))) {
				error = SO_EOPENSSL;
				goto error;
			}

			BIO_ctrl_set_connected(bio, &peer);

			SSL_set_bio(so->ssl.ctx, bio, bio);
			SSL_set_read_ahead(so->ssl.ctx, 1);
		} else {
			BIO *bio;

			if (!(bio = so_newbio(so, &error)))
				goto error;

			SSL_set_bio(so->ssl.ctx, bio, bio);
		}

		if (so->ssl.accept) {
			SSL_set_accept_state(so->ssl.ctx);
		} else {
			SSL_set_connect_state(so->ssl.ctx);
		}

		so->ssl.state++;
	}
	/* FALL THROUGH */
	case 1:
		rval = SSL_do_handshake(so->ssl.ctx);

		if (rval > 0) {
			/* SUCCESS (continue to next state) */
			;;
		} else {
			/* ERROR (either need I/O or a plain error) or SHUTDOWN */
			so->events &= ~(POLLIN|POLLOUT);

			error = ssl_error(so->ssl.ctx, rval, &so->events);

			goto error;
		} /* (rval) */

		so->ssl.state++;
		/* FALL THROUGH */
	case 2:
		/*
		 * NOTE: Must call SSL_get_peer_certificate() first, which
		 * processes the certificate. SSL_get_verify_result() merely
		 * returns the result of this processing.
		 */
		peer = SSL_get_peer_certificate(so->ssl.ctx);
		so->ssl.vrfd = (peer && SSL_get_verify_result(so->ssl.ctx) == X509_V_OK);
		x509_discard(&peer);

		so->ssl.state++;
		/* FALL THROUGH */
	case 3:
		if (so->opts.tls_verify && !so->ssl.vrfd) {
			error = SO_ENOTVRFD;

			goto error;
		}

		so->ssl.state++;
		/* FALL THROUGH */
	case 4:
		break;
	} /* switch(so->ssl.state) */

#if SOCKET_DEBUG
	if (SOCKET_DEBUG) {
		const SSL_CIPHER *cipher = SSL_get_current_cipher(so->ssl.ctx);

		so_trace(SO_T_STARTTLS, so->fd, so->host, so->ssl.ctx,
			"%s-%s", SSL_get_version(so->ssl.ctx), SSL_CIPHER_get_name(cipher));
	}
#endif

	so_pipeok(so, 0);

	return 0;
error:
	if (error != SO_EAGAIN)
		so_trace(SO_T_STARTTLS, so->fd, so->host, so->ssl.ctx, "%s", so_strerror(error));

	so_pipeok(so, 0);

	return error;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xf0, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x0, 0xd0(%rax)
je 0x307fe
movq -0x10(%rbp), %rax
movl 0xd0(%rax), %eax
movl %eax, -0x4(%rbp)
jmp 0x30b53
movq -0x10(%rbp), %rdi
xorl %esi, %esi
callq 0x2e860
callq 0x10280
movq -0x10(%rbp), %rax
movl 0xd4(%rax), %eax
movq %rax, -0xc8(%rbp)
subq $0x4, %rax
ja 0x30ac5
movq -0xc8(%rbp), %rax
leaq 0x19071(%rip), %rcx     # 0x498a8
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x10(%rbp), %rax
movl 0x5c(%rax), %eax
andl $0xf000, %eax           # imm = 0xF000
cmpl $0xc000, %eax           # imm = 0xC000
jne 0x30939
movq -0x10(%rbp), %rax
cmpl $0x2, 0x64(%rax)
jne 0x30939
leaq -0xa0(%rbp), %rdi
xorl %esi, %esi
movl $0x80, %edx
callq 0xf7d0
movq -0x10(%rbp), %rax
movl 0x58(%rax), %edi
leaq -0xa0(%rbp), %rax
movq %rax, -0xb0(%rbp)
movl $0x80, -0xb4(%rbp)
movq -0xb0(%rbp), %rsi
leaq -0xb4(%rbp), %rdx
callq 0xfa00
movl %eax, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
je 0x308c1
callq 0xf0a0
movl (%rax), %eax
movl %eax, -0x20(%rbp)
jmp 0x30ad9
movq -0x10(%rbp), %rax
movl 0x58(%rax), %edi
xorl %esi, %esi
callq 0xf980
movq %rax, -0xa8(%rbp)
cmpq $0x0, %rax
jne 0x308e8
movl $0x8c9c94c7, -0x20(%rbp) # imm = 0x8C9C94C7
jmp 0x30ad9
movq -0xa8(%rbp), %rdi
movl $0x20, %esi
xorl %eax, %eax
movl %eax, %edx
leaq -0xa0(%rbp), %rcx
callq 0xf370
movq -0x10(%rbp), %rax
movq 0xc8(%rax), %rdi
movq -0xa8(%rbp), %rsi
movq -0xa8(%rbp), %rdx
callq 0xfe60
movq -0x10(%rbp), %rax
movq 0xc8(%rax), %rdi
movl $0x1, %esi
callq 0x10720
jmp 0x30976
movq -0x10(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x30ca0
movq %rax, -0xc0(%rbp)
cmpq $0x0, %rax
jne 0x30958
jmp 0x30ad9
movq -0x10(%rbp), %rax
movq 0xc8(%rax), %rdi
movq -0xc0(%rbp), %rsi
movq -0xc0(%rbp), %rdx
callq 0xfe60
movq -0x10(%rbp), %rax
testb $0x1, 0xd8(%rax)
je 0x30995
movq -0x10(%rbp), %rax
movq 0xc8(%rax), %rdi
callq 0xf780
jmp 0x309a5
movq -0x10(%rbp), %rax
movq 0xc8(%rax), %rdi
callq 0xf500
movq -0x10(%rbp), %rax
movl 0xd4(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0xd4(%rax)
movq -0x10(%rbp), %rax
movq 0xc8(%rax), %rdi
callq 0x103e0
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
jle 0x309d3
jmp 0x30a0e
movq -0x10(%rbp), %rax
movswl 0xb0(%rax), %ecx
andl $-0x6, %ecx
movw %cx, 0xb0(%rax)
movq -0x10(%rbp), %rax
movq 0xc8(%rax), %rdi
movl -0x1c(%rbp), %esi
movq -0x10(%rbp), %rdx
addq $0xb0, %rdx
callq 0x2e970
movl %eax, -0x20(%rbp)
jmp 0x30ad9
movq -0x10(%rbp), %rax
movl 0xd4(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0xd4(%rax)
movq -0x10(%rbp), %rax
movq 0xc8(%rax), %rdi
callq 0x10ae0
movq %rax, -0x18(%rbp)
xorl %eax, %eax
cmpq $0x0, -0x18(%rbp)
movb %al, -0xc9(%rbp)
je 0x30a61
movq -0x10(%rbp), %rax
movq 0xc8(%rax), %rdi
callq 0xf550
cmpq $0x0, %rax
sete %al
movb %al, -0xc9(%rbp)
movb -0xc9(%rbp), %cl
movq -0x10(%rbp), %rax
andb $0x1, %cl
movb %cl, 0xd9(%rax)
leaq -0x18(%rbp), %rdi
callq 0x30d70
movq -0x10(%rbp), %rax
movl 0xd4(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0xd4(%rax)
movq -0x10(%rbp), %rax
testb $0x1, 0x38(%rax)
je 0x30ab0
movq -0x10(%rbp), %rax
testb $0x1, 0xd9(%rax)
jne 0x30ab0
movl $0x8c9c94c9, -0x20(%rbp) # imm = 0x8C9C94C9
jmp 0x30ad9
movq -0x10(%rbp), %rax
movl 0xd4(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0xd4(%rax)
jmp 0x30ac5
movq -0x10(%rbp), %rdi
xorl %esi, %esi
callq 0x2f4a0
movl $0x0, -0x4(%rbp)
jmp 0x30b53
cmpl $0xb, -0x20(%rbp)
je 0x30b42
movq -0x10(%rbp), %rax
movl 0x58(%rax), %eax
movl %eax, -0xe4(%rbp)
movq -0x10(%rbp), %rax
movq 0xa8(%rax), %rax
movq %rax, -0xe0(%rbp)
movq -0x10(%rbp), %rax
movq 0xc8(%rax), %rax
movq %rax, -0xd8(%rbp)
movl -0x20(%rbp), %edi
callq 0xfcd0
movl -0xe4(%rbp), %esi
movq -0xe0(%rbp), %rdx
movq -0xd8(%rbp), %rcx
movq %rax, %r9
movl $0x1, %edi
leaq 0x185e6(%rip), %r8      # 0x49121
movb $0x0, %al
callq 0x2eb90
movq -0x10(%rbp), %rdi
xorl %esi, %esi
callq 0x2f4a0
movl -0x20(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xf0, %rsp
popq %rbp
retq
nop