// File: /workspace/github_c_makefile_star2_O1/sharpyfox[P]citrusleaf-client/src/cl_lookup.c
// Function: cl_lookup
int
cl_lookup(cl_cluster *asc, char *hostname, short port, cf_vector *sockaddr_in_v)
{
	// do the gethostbyname to find the IP address
	size_t hstbuflen = 1024;
	uint8_t	stack_hstbuf[hstbuflen];
	void *tmphstbuf = stack_hstbuf;
	int rv, herr, addrmapsz;
	struct hostent hostbuf, *hp;
	cl_addrmap *map;
	int retry = 0;
	//Find if there is an alternate address that should be used for this hostname.
	if (asc && (asc->host_addr_map_v.len > 0)) {
		addrmapsz = asc->host_addr_map_v.len;
		for (int i=0; i<addrmapsz; i++) {
			map = cf_vector_pointer_get(&asc->host_addr_map_v, i);
			if (map && strcmp(map->orig, hostname) == 0) {
				//found a mapping for this address. Use the alternate one.
				cf_debug("Using %s instead of %s", map->alt, hostname);
				hostname = map->alt;
				break;
			}
		}
	}

	do {
#ifdef OSX // on OSX, gethostbyname is thread safe and there is no '_r' version 
		hp = gethostbyname2(hostname, AF_INET);
		rv = 0;
		if(hp == NULL){
			herr = h_errno; // I'm hoping this is thread-safe too, in the Mac world...
		}
#else
		rv = gethostbyname2_r(hostname, AF_INET, &hostbuf, tmphstbuf, hstbuflen,
				&hp, &herr);
#endif
		/* TRY_AGAIN for a maximun of 3 times, after which throw an error */
		if(retry > 2) {
			cf_error("gethostbyname of %s - maxmimum retries failed", hostname);
			retry = 0;
			return -1;
		}
		if (hp == NULL) {
			hostname = hostname ? hostname : "NONAME";
			switch(herr) {
				case HOST_NOT_FOUND:
					cf_error("gethostbyname says no host at %s", hostname);
					break;
				case NO_ADDRESS:
					cf_error("gethostbyname of %s says invalid address (errno %d)", hostname, herr);
					break;
				case NO_RECOVERY:
					cf_error("gethostbyname of %s says form error (errno %d)", hostname, herr);
					break;
				case TRY_AGAIN:
					cf_error("gethostbyname of %s returned TRY_AGAIN, try again (rv=%d)", hostname, rv);
					retry++;
					continue;
				default:
					cf_error("gethostbyname of %s returned an unknown error (errno %d)", hostname, herr);
					break;
			}
			if (tmphstbuf != stack_hstbuf)		free(tmphstbuf);
			return(-1);
		}
		else if (rv != 0) {
			if (rv == ERANGE) {
				hstbuflen *= 2;
				if (tmphstbuf == stack_hstbuf)
					tmphstbuf = malloc(hstbuflen);
				else
					tmphstbuf = realloc (tmphstbuf, hstbuflen);
				if (!tmphstbuf) {
					cf_error("malloc fail");
					return(-1);
				}
			}
			else if (rv == EAGAIN || herr == TRY_AGAIN) {
				cf_error("gethostbyname returned EAGAIN, try again");
				retry++;
			}
			else if (rv == ETIMEDOUT) {
				cf_error("gethostbyname for %s timed out", hostname ? (hostname): "NONAME");
				if (tmphstbuf != stack_hstbuf)		free(tmphstbuf);
				return(-1);
			}
			else {
				cf_error("gethostbyname returned an unknown error %d %d (errno %d)",rv,herr, errno);
				if (tmphstbuf != stack_hstbuf)		free(tmphstbuf);
				return(-1);
			}
		}
	} while ((rv != 0) || (hp == NULL));

#ifdef DEBUG
	cf_debug("host lookup: %s canonical: %s addrtype %d length: %d",
		hostname, hp->h_name, hp->h_addrtype, hp->h_length);

	for (int i=0;hp->h_aliases[i];i++) {
		cf_debug("  alias %d: %s",i, hp->h_aliases[i]);
	}
	for (int i=0;hp->h_addr_list[i];i++) {
		// todo: print something about the actual address
		cf_debug("  address %d: %x",i,*(uint32_t *) hp->h_addr_list[i]);
	}
#endif

	if (hp->h_addrtype != AF_INET) {
		cf_error("unknown address type %d", hp->h_addrtype);
		if (tmphstbuf != stack_hstbuf)		free(tmphstbuf);
		return(-1);
	}
	
	// sockaddr_in_v is passed as NULL from caller which needs
	// to only check if lookup succeeds. If reach here it is 
	// a successful lookup. 
	if (sockaddr_in_v == NULL) {
		goto ret_success;
	}
	
	// Move into vector
	for (int i=0;hp->h_addr_list[i];i++) {
		struct sockaddr_in 	addr;
		memset(&addr,0,sizeof(addr));
		addr.sin_family = hp->h_addrtype;
		addr.sin_addr.s_addr = *(uint32_t *) hp->h_addr_list[i];
		addr.sin_port = htons(port);
		
		cf_vector_append_unique(sockaddr_in_v, &addr);
	}

ret_success:
	if (tmphstbuf != stack_hstbuf)		free(tmphstbuf);
	
	return(0);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x478, %rsp            # imm = 0x478
movq %rcx, 0x48(%rsp)
movq %rsi, %r14
testq %rdi, %rdi
movl %edx, 0x2c(%rsp)
je 0x8f0f
movq %rdi, %rbx
movl 0xb4(%rdi), %r12d
testl %r12d, %r12d
jle 0x8f0f
addq $0xa8, %rbx
xorl %ebp, %ebp
leaq 0x50(%rsp), %r15
movq %rbx, %rdi
movl %ebp, %esi
movq %r15, %rdx
callq 0xec6f
movq 0x50(%rsp), %r13
testq %r13, %r13
je 0x8ed2
movq (%r13), %rdi
movq %r14, %rsi
callq 0x2350
testl %eax, %eax
je 0x8edb
incl %ebp
cmpl %ebp, %r12d
jne 0x8eab
jmp 0x8f0f
leaq 0xe3e6(%rip), %rax      # 0x172c8
movl (%rax), %eax
cmpl $0x3, %eax
jl 0x8f0b
leaq 0xe3e0(%rip), %rax      # 0x172d0
movq (%rax), %r8
movq 0x8(%r13), %rdx
leaq 0x7d12(%rip), %rsi      # 0x10c10
movl $0x3, %edi
movq %r14, %rcx
xorl %eax, %eax
callq *%r8
movq 0x8(%r13), %r14
movl $0x400, %r13d           # imm = 0x400
leaq 0x70(%rsp), %rbx
leaq 0x7d34(%rip), %rbp      # 0x10c55
xorl %r15d, %r15d
leaq 0x14(%rsp), %rax
movq %rax, (%rsp)
movq %r14, %rdi
movl $0x2, %esi
leaq 0x50(%rsp), %rdx
movq %rbx, %rcx
movq %r13, %r8
leaq 0x18(%rsp), %r9
callq 0x23e0
cmpl $0x3, %r15d
jge 0x9117
movl %eax, %r12d
cmpq $0x0, 0x18(%rsp)
je 0x8f8f
testl %r12d, %r12d
je 0x903b
cmpl $0x22, %r12d
jne 0x8fd3
addq %r13, %r13
leaq 0x70(%rsp), %rax
cmpq %rax, %rbx
je 0x9027
movq %rbx, %rdi
movq %r13, %rsi
callq 0x2470
jmp 0x902f
testq %r14, %r14
cmoveq %rbp, %r14
movl 0x14(%rsp), %ecx
leaq 0xe327(%rip), %rax      # 0x172c8
movl (%rax), %eax
cmpl $0x2, %ecx
jne 0x90d5
testl %eax, %eax
js 0x8fce
leaq 0xe319(%rip), %rax      # 0x172d0
movq (%rax), %r8
xorl %edi, %edi
leaq 0x7d1d(%rip), %rsi      # 0x10ce0
movq %r14, %rdx
movl %r12d, %ecx
xorl %eax, %eax
callq *%r8
incl %r15d
jmp 0x903b
movq %rbx, 0x20(%rsp)
movq %rbp, %rbx
cmpl $0xb, %r12d
sete %al
movl 0x14(%rsp), %ebp
cmpl $0x2, %ebp
sete %cl
orb %al, %cl
cmpb $0x1, %cl
jne 0x91e8
leaq 0xe2ca(%rip), %rax      # 0x172c8
cmpl $0x0, (%rax)
js 0x901a
leaq 0xe2c6(%rip), %rax      # 0x172d0
movq (%rax), %rcx
xorl %edi, %edi
leaq 0x7d49(%rip), %rsi      # 0x10d5f
xorl %eax, %eax
callq *%rcx
incl %r15d
movq %rbx, %rbp
movq 0x20(%rsp), %rbx
jmp 0x903b
movq %r13, %rdi
callq 0x22e0
movq %rax, %rbx
testq %rax, %rax
je 0x921e
testl %r12d, %r12d
setne %cl
movq 0x18(%rsp), %rax
testq %rax, %rax
sete %dl
orb %cl, %dl
jne 0x8f24
movl 0x10(%rax), %edx
cmpl $0x2, %edx
movl 0x2c(%rsp), %ebp
jne 0x914b
movq 0x48(%rsp), %r12
testq %r12, %r12
je 0x90ce
movq 0x18(%rsp), %rax
movq 0x18(%rax), %rcx
cmpq $0x0, (%rcx)
je 0x90ce
rolw $0x8, %bp
movl $0x8, %r15d
leaq 0x30(%rsp), %r14
xorps %xmm0, %xmm0
movaps %xmm0, 0x30(%rsp)
movzwl 0x10(%rax), %eax
movw %ax, 0x30(%rsp)
movq (%rcx), %rax
movl (%rax), %eax
movl %eax, 0x34(%rsp)
movw %bp, 0x32(%rsp)
movq %r12, %rdi
movq %r14, %rsi
callq 0xebdb
movq 0x18(%rsp), %rax
movq 0x18(%rax), %rdx
leaq (%rdx,%r15), %rcx
cmpq $0x0, (%rdx,%r15)
leaq 0x8(%r15), %r15
jne 0x908c
xorl %ebp, %ebp
jmp 0x91c2
cmpl $0x4, %ecx
je 0x9170
cmpl $0x3, %ecx
je 0x9187
cmpl $0x1, %ecx
jne 0x919e
testl %eax, %eax
js 0x91bd
leaq 0xe1d1(%rip), %rax      # 0x172d0
movq (%rax), %rcx
leaq 0x7b53(%rip), %rsi      # 0x10c5c
xorl %edi, %edi
movq %r14, %rdx
xorl %eax, %eax
callq *%rcx
jmp 0x91bd
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
leaq 0xe1a5(%rip), %rax      # 0x172c8
cmpl $0x0, (%rax)
js 0x91d4
leaq 0xe19d(%rip), %rax      # 0x172d0
movq (%rax), %rcx
leaq 0x7aea(%rip), %rsi      # 0x10c27
xorl %edi, %edi
movq %r14, %rdx
xorl %eax, %eax
callq *%rcx
jmp 0x91d4
leaq 0xe176(%rip), %rax      # 0x172c8
cmpl $0x0, (%rax)
js 0x91bd
leaq 0xe172(%rip), %rax      # 0x172d0
movq (%rax), %rcx
leaq 0x7c78(%rip), %rsi      # 0x10de0
xorl %edi, %edi
xorl %eax, %eax
callq *%rcx
jmp 0x91bd
testl %eax, %eax
js 0x91bd
leaq 0xe155(%rip), %rax      # 0x172d0
movq (%rax), %r8
leaq 0x7af8(%rip), %rsi      # 0x10c7d
jmp 0x91b3
testl %eax, %eax
js 0x91bd
leaq 0xe13e(%rip), %rax      # 0x172d0
movq (%rax), %r8
leaq 0x7b15(%rip), %rsi      # 0x10cb1
jmp 0x91b3
testl %eax, %eax
js 0x91bd
leaq 0xe127(%rip), %rax      # 0x172d0
movq (%rax), %r8
leaq 0x7b67(%rip), %rsi      # 0x10d1a
xorl %edi, %edi
movq %r14, %rdx
xorl %eax, %eax
callq *%r8
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
leaq 0x70(%rsp), %rax
cmpq %rax, %rbx
je 0x91d4
movq %rbx, %rdi
callq 0x22c0
movl %ebp, %eax
addq $0x478, %rsp            # imm = 0x478
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpl $0x6e, %r12d
leaq 0xe0d5(%rip), %rax      # 0x172c8
movl (%rax), %eax
jne 0x9248
testl %eax, %eax
js 0x9271
leaq 0xe0ce(%rip), %rax      # 0x172d0
movq (%rax), %rcx
testq %r14, %r14
cmovneq %r14, %rbx
leaq 0x7b75(%rip), %rsi      # 0x10d88
xorl %edi, %edi
movq %rbx, %rdx
xorl %eax, %eax
callq *%rcx
jmp 0x9271
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
leaq 0xe09e(%rip), %rax      # 0x172c8
cmpl $0x0, (%rax)
js 0x91d4
leaq 0xe09a(%rip), %rax      # 0x172d0
movq (%rax), %rcx
leaq 0x7b13(%rip), %rsi      # 0x10d53
xorl %edi, %edi
xorl %eax, %eax
callq *%rcx
jmp 0x91d4
testl %eax, %eax
js 0x9271
leaq 0xe07d(%rip), %rax      # 0x172d0
movq (%rax), %r14
callq 0x2040
movl (%rax), %r8d
leaq 0x7b42(%rip), %rsi      # 0x10da7
xorl %edi, %edi
movl %r12d, %edx
movl %ebp, %ecx
xorl %eax, %eax
callq *%r14
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
leaq 0x70(%rsp), %rax
movq 0x20(%rsp), %rdi
cmpq %rax, %rdi
jne 0x91cf
jmp 0x91d4
nop