// File: /workspace/github_cpp_makefile_star2_O3/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 0x9e68
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 0x9e71
testb %r13b, %r13b
je 0x9dbe
cmpw $0xa, (%r14)
movl $0x1c, %eax
movl $0x10, %edx
cmovel %eax, %edx
movl %ebx, %edi
movq %r14, %rsi
callq 0x3080
testl %eax, %eax
jne 0x9e95
leaq 0x4(%rsp), %rcx
movl %ebx, %edi
movl $0x1, %esi
movl $0x1d, %edx
movl $0x4, %r8d
callq 0x3600
testl %eax, %eax
jne 0x9e7a
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 0x9e83
leaq 0x2344(%rip), %rax      # 0xc158
movl (%rax), %edx
movl %ebx, %edi
movq %r14, %rsi
callq 0x9ece
testb %al, %al
je 0x9e8c
testb %bpl, %bpl
jne 0x9ea6
movzwl (%r14), %eax
cmpl $0x2, %eax
je 0x9e40
cmpl $0xa, %eax
jne 0x9ea6
cmpb $-0x1, 0x8(%r14)
jne 0x9ea6
jmp 0x9e50
movl $0xf0, %eax
andl 0x4(%r14), %eax
cmpl $0xe0, %eax
jne 0x9ea6
movl %ebx, %edi
movq %r14, %rsi
callq *0x856d(%rip)           # 0x123c8
testl %eax, %eax
je 0x9ea6
leaq 0x37e3(%rip), %rdi      # 0xd649
jmp 0x9e9c
leaq 0x3747(%rip), %rdi      # 0xd5b6
jmp 0x9e9c
leaq 0x3760(%rip), %rdi      # 0xd5d8
jmp 0x9e9c
leaq 0x3782(%rip), %rdi      # 0xd603
jmp 0x9e9c
leaq 0x3792(%rip), %rdi      # 0xd61c
jmp 0x9e9c
leaq 0x37ae(%rip), %rdi      # 0xd641
jmp 0x9e9c
leaq 0x3747(%rip), %rdi      # 0xd5e3
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