// File: /workspace/github_c_makefile_star2_O3/open-mesh-mirror[P]batmand/batman.c
// Function: choose_gw
void choose_gw(void)
{
	struct list_head *pos;
	struct gw_node *gw_node, *tmp_curr_gw = NULL;
	uint8_t max_gw_class = 0, max_tq = 0;
	uint32_t current_time, max_gw_factor = 0, tmp_gw_factor = 0;
	int download_speed, upload_speed;
	char orig_str[ADDR_STR_LEN];
	prof_start( PROF_choose_gw );


	current_time = get_time_msec();
	if ((routing_class == 0) || ((routing_class < 4) && ((int64_t)(get_time_msec64() - (originator_interval * local_win_size)) < 0))) {

		prof_stop( PROF_choose_gw );
		return;

	}

	if ( list_empty( &gw_list ) ) {

		if ( curr_gateway != NULL ) {

			debug_output( 3, "Removing default route - no gateway in range\n" );

			del_default_route();

		}

		prof_stop( PROF_choose_gw );
		return;

	}

	list_for_each( pos, &gw_list ) {

		gw_node = list_entry( pos, struct gw_node, list );

		/* ignore this gateway if recent connection attempts were unsuccessful */
		/* if it is our only gateway retry immediately */
		if ((gw_node != (struct gw_node *)gw_list.next) || (gw_node->list.next != (struct list_head *)&gw_list)) {

			if ((int)(current_time - (gw_node->last_failure + 30000)) < 0)
				continue;

		}

		if ( gw_node->orig_node->router == NULL )
			continue;

		if ( gw_node->deleted )
			continue;

		switch ( routing_class ) {

			case 1: /* fast connection */
				get_gw_speeds( gw_node->orig_node->gwflags, &download_speed, &upload_speed );

				if (((tmp_gw_factor = (((gw_node->orig_node->router->tq_avg * 100 ) / local_win_size) *
								  ((gw_node->orig_node->router->tq_avg * 100) / local_win_size) *
								     (download_speed / 64))) > max_gw_factor) ||
								  ((tmp_gw_factor == max_gw_factor) && (gw_node->orig_node->router->tq_avg > max_tq)))
					tmp_curr_gw = gw_node;
				break;

			default: /* stable connection (use best statistic) */
				 /* fast-switch (use best statistic but change as soon as a better gateway appears) */
				 /* late-switch (use best statistic but change as soon as a better gateway appears which has $routing_class more tq points) */
				if (gw_node->orig_node->router->tq_avg > max_tq)
					tmp_curr_gw = gw_node;
				break;

		}

		if ( gw_node->orig_node->gwflags > max_gw_class )
			max_gw_class = gw_node->orig_node->gwflags;

		if (gw_node->orig_node->router->tq_avg > max_tq)
			max_tq = gw_node->orig_node->router->tq_avg;

		if ( tmp_gw_factor > max_gw_factor )
			max_gw_factor = tmp_gw_factor;

		if ( ( pref_gateway != 0 ) && ( pref_gateway == gw_node->orig_node->orig ) ) {

			tmp_curr_gw = gw_node;

			addr_to_string( tmp_curr_gw->orig_node->orig, orig_str, ADDR_STR_LEN );
			debug_output( 3, "Preferred gateway found: %s (gw_flags: %i, tq: %i, gw_product: %i)\n", orig_str, gw_node->orig_node->gwflags, gw_node->orig_node->router->tq_avg, tmp_gw_factor );

			break;

		}

	}


	if ( curr_gateway != tmp_curr_gw ) {

		if ( curr_gateway != NULL ) {

			if ( tmp_curr_gw != NULL )
				debug_output( 3, "Removing default route - better gateway found\n" );
			else
				debug_output( 3, "Removing default route - no gateway in range\n" );

			del_default_route();

		}

		curr_gateway = tmp_curr_gw;

		/* may be the last gateway is now gone */
		if ( ( curr_gateway != NULL ) && ( !is_aborted() ) ) {

			addr_to_string( curr_gateway->orig_node->orig, orig_str, ADDR_STR_LEN );
			debug_output( 3, "Adding default route to %s (gw_flags: %i, tq: %i, gw_product: %i)\n", orig_str, max_gw_class, max_tq, max_gw_factor );

			add_default_route();

		}

	}

	prof_stop( PROF_choose_gw );
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
xorl %edi, %edi
callq 0x6bbc
callq 0xb3f0
movl %eax, %ebp
movb 0x14552(%rip), %al      # 0x172ba
testb %al, %al
je 0x2dc2
cmpb $0x3, %al
ja 0x2d8d
callq 0xb46c
movswq 0x1450d(%rip), %rcx     # 0x1728a
movzbl 0x14513(%rip), %edx     # 0x17297
imulq %rcx, %rdx
cmpq %rdx, %rax
js 0x2dc2
leaq 0x1458c(%rip), %r14     # 0x17320
movq %r14, %rdi
callq 0x5bfb
testl %eax, %eax
je 0x2dd7
cmpq $0x0, 0x14518(%rip)     # 0x172c0
je 0x2dc2
leaq 0xcbfe(%rip), %rsi      # 0xf9af
movl $0x3, %edi
xorl %eax, %eax
callq 0xd88c
callq 0xbbf4
xorl %edi, %edi
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x6bd8
movq 0x14542(%rip), %rsi     # 0x17320
cmpq %r14, %rsi
je 0x2efc
addl $0xffff8ad0, %ebp       # imm = 0xFFFF8AD0
movb 0x144c6(%rip), %r8b     # 0x172ba
movzbl 0x1449c(%rip), %eax     # 0x17297
movl %eax, 0x4(%rsp)
movl 0x144cb(%rip), %edi     # 0x172d0
movq %rsi, %rbx
xorl %r15d, %r15d
xorl %edx, %edx
xorl %r13d, %r13d
xorl %r12d, %r12d
xorl %r9d, %r9d
cmpq %rsi, %rbx
jne 0x2e20
cmpq %r14, (%rbx)
je 0x2e29
cmpl 0x14(%rbx), %ebp
js 0x2ee7
movq 0x8(%rbx), %r10
movq 0x8(%r10), %rax
testq %rax, %rax
je 0x2ee7
cmpl $0x0, 0x18(%rbx)
jne 0x2ee7
cmpb $0x1, %r8b
jne 0x2ea6
movq %r9, 0x8(%rsp)
movl 0x34(%r10), %r11d
movl %r11d, %r15d
shrl $0x2, %r15d
andl $0x20, %r15d
orl $0x40, %r15d
movl %r11d, %ecx
shrb $0x3, %cl
andb $0xf, %cl
shll %cl, %r15d
movzbl 0x19(%rax), %ecx
imull $0x64, %ecx, %eax
movl %edx, %r9d
xorl %edx, %edx
divw 0x4(%rsp)
movl %r9d, %edx
movzwl %ax, %eax
imull %eax, %eax
shrl $0x6, %r15d
imull %eax, %r15d
cmpl %r9d, %r15d
ja 0x2ea1
jne 0x2ef5
cmpb %r13b, %cl
movq 0x8(%rsp), %r9
jbe 0x2eb4
movq %rbx, %r9
jmp 0x2eb4
movb 0x19(%rax), %cl
cmpb %r13b, %cl
cmovaq %rbx, %r9
movb 0x34(%r10), %r11b
movzbl %r11b, %eax
movzbl %r12b, %r12d
cmpb %r12b, %al
cmoval %eax, %r12d
movzbl %cl, %eax
cmpb %r13b, %al
movzbl %r13b, %ecx
cmoval %eax, %ecx
cmpl %edx, %r15d
cmoval %r15d, %edx
movl %ecx, %r13d
testl %edi, %edi
je 0x2ee7
cmpl (%r10), %edi
je 0x2fbe
movq (%rbx), %rbx
cmpq %r14, %rbx
jne 0x2e16
jmp 0x2f07
movq 0x8(%rsp), %r9
jmp 0x2eb4
xorl %r9d, %r9d
xorl %r12d, %r12d
xorl %r13d, %r13d
xorl %edx, %edx
movq 0x143b2(%rip), %rax     # 0x172c0
cmpq %r9, %rax
je 0x2fa8
testq %rax, %rax
je 0x2f4c
testq %r9, %r9
leaq 0xca89(%rip), %rax      # 0xf9af
leaq 0xcaf4(%rip), %rsi      # 0xfa21
cmoveq %rax, %rsi
movl $0x3, %edi
xorl %eax, %eax
movl %edx, %ebx
movq %r9, %r14
callq 0xd88c
callq 0xbbf4
movq %r14, %r9
movl %ebx, %edx
movq %r9, 0x1436d(%rip)      # 0x172c0
testq %r9, %r9
je 0x2fa8
movl %edx, %ebx
callq 0xbbdb
testb %al, %al
jne 0x2fa8
movq 0x14356(%rip), %rax     # 0x172c0
movq 0x8(%rax), %rax
movl (%rax), %edi
leaq 0x10(%rsp), %r14
movq %r14, %rsi
movl $0x10, %edx
callq 0xbbac
movzbl %r12b, %ecx
movzbl %r13b, %r8d
leaq 0xcabf(%rip), %rsi      # 0xfa50
movl $0x3, %edi
movq %r14, %rdx
movl %ebx, %r9d
xorl %eax, %eax
callq 0xd88c
callq 0xbc03
xorl %edi, %edi
callq 0x6bd8
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x10(%rsp), %r14
movq %r14, %rsi
movl %edx, %ebp
movl $0x10, %edx
callq 0xbbac
movq 0x8(%rbx), %rax
movzbl 0x34(%rax), %ecx
movq 0x8(%rax), %rax
movzbl 0x19(%rax), %r8d
leaq 0xc9f3(%rip), %rsi      # 0xf9dd
movl $0x3, %edi
movq %r14, %rdx
movl %r15d, %r9d
xorl %eax, %eax
callq 0xd88c
movl %ebp, %edx
movq %rbx, %r9
jmp 0x2f07