// File: /workspace/github_cpp_makefile_star2_O1/hugosantos[P]dbeacon/dbeacon_posix.cpp
// Function: SetupSocket(address const&, bool, bool)
int SetupSocket(const address &addr, bool shouldbind, bool ssm) {
	int af_family = addr.family();
	int level = addr.optlevel();

	int sock = socket(af_family, SOCK_DGRAM, 0);
	if (sock < 0) {
		perror("Failed to create multicast socket");
		return -1;
	}

	int on = 1;

	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) != 0) {
		perror("setsockopt");
		return -1;
	}

	if (shouldbind) {
		if (bind(sock, addr.saddr(), addr.addrlen()) != 0) {
			perror("Failed to bind multicast socket");
			return -1;
		}
	}

#ifdef SO_TIMESTAMP
	if (setsockopt(sock, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)) != 0) {
		perror("setsockopt(SO_TIMESTAMP)");
		return -1;
	}
#endif

	int type = level == IPPROTO_IPV6 ?
#ifdef IPV6_RECVHOPLIMIT
				IPV6_RECVHOPLIMIT
#else
				IPV6_HOPLIMIT
#endif
				:
#ifdef IP_RECVTTL
				IP_RECVTTL;
#else
				IP_TTL;
#endif

	if (setsockopt(sock, level, type, &on, sizeof(on)) != 0) {
		perror("receiving hop limit/ttl setsockopt()");
		return -1;
	}

	if (!SetHops(sock, addr, defaultTTL)) {
		perror("SetHops");
		return -1;
	}

	if (!ssm && addr.is_multicast()) {
		if (MulticastListen(sock, addr) != 0) {
			perror("Failed to join multicast group");
			return -1;
		}
	}

	return sock;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl %edx, %ebp
movl %esi, %r13d
movq %rdi, %r14
movzwl (%rdi), %r12d
xorl %eax, %eax
cmpl $0xa, %r12d
movl $0x29, %r15d
cmovnel %eax, %r15d
movl %r12d, %edi
movl $0x2, %esi
xorl %edx, %edx
callq 0x30d0
testl %eax, %eax
js 0x9f10
movl %eax, %ebx
leaq 0x4(%rsp), %rcx
movl $0x1, (%rcx)
movl %eax, %edi
movl $0x1, %esi
movl $0x2, %edx
movl $0x4, %r8d
callq 0x3600
testl %eax, %eax
jne 0x9f19
testb %r13b, %r13b
je 0x9e5f
cmpw $0xa, (%r14)
movl $0x1c, %eax
movl $0x10, %edx
cmovel %eax, %edx
movl %ebx, %edi
movq %r14, %rsi
callq 0x3080
testl %eax, %eax
jne 0x9f3d
leaq 0x4(%rsp), %rcx
movl %ebx, %edi
movl $0x1, %esi
movl $0x1d, %edx
movl $0x4, %r8d
callq 0x3600
testl %eax, %eax
jne 0x9f22
cmpw $0xa, %r12w
movl $0x33, %eax
movl $0xc, %edx
cmovel %eax, %edx
leaq 0x4(%rsp), %rcx
movl %ebx, %edi
movl %r15d, %esi
movl $0x4, %r8d
callq 0x3600
testl %eax, %eax
jne 0x9f2b
leaq 0x22a3(%rip), %rax      # 0xc158
movl (%rax), %edx
movl %ebx, %edi
movq %r14, %rsi
callq 0x9f76
testb %al, %al
je 0x9f34
testb %bpl, %bpl
jne 0x9f4e
movzwl (%r14), %eax
cmpl $0x2, %eax
je 0x9ee3
cmpl $0xa, %eax
jne 0x9f4e
cmpb $-0x1, 0x8(%r14)
jmp 0x9ef1
movl $0xf0, %eax
andl 0x4(%r14), %eax
cmpl $0xe0, %eax
sete %al
testb %al, %al
je 0x9f4e
movl %ebx, %edi
movq %r14, %rsi
callq *0x84c5(%rip)           # 0x123c8
testl %eax, %eax
je 0x9f4e
leaq 0x3742(%rip), %rdi      # 0xd650
jmp 0x9f44
leaq 0x36a6(%rip), %rdi      # 0xd5bd
jmp 0x9f44
leaq 0x36bf(%rip), %rdi      # 0xd5df
jmp 0x9f44
leaq 0x36e1(%rip), %rdi      # 0xd60a
jmp 0x9f44
leaq 0x36f1(%rip), %rdi      # 0xd623
jmp 0x9f44
leaq 0x370d(%rip), %rdi      # 0xd648
jmp 0x9f44
leaq 0x36a6(%rip), %rdi      # 0xd5ea
callq 0x3320
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
movl %ebx, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop