// File: /workspace/github_c_makefile_star2_O1/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 0x6880
callq 0xb0fc
movl %eax, %ebp
movb 0x14552(%rip), %al      # 0x172ba
testb %al, %al
je 0x2fa0
cmpb $0x3, %al
ja 0x2d95
callq 0xb178
movswq 0x14509(%rip), %rcx     # 0x1728a
movzbl 0x1450f(%rip), %edx     # 0x17297
imulq %rcx, %rdx
cmpq %rdx, %rax
js 0x2fa0
leaq 0x14584(%rip), %r14     # 0x17320
movq %r14, %rdi
callq 0x5be7
testl %eax, %eax
je 0x2dd3
cmpq $0x0, 0x14510(%rip)     # 0x172c0
je 0x2fa0
leaq 0xcbf2(%rip), %rsi      # 0xf9af
movl $0x3, %edi
xorl %eax, %eax
callq 0xd5b0
callq 0xb900
jmp 0x2fa0
movq 0x14546(%rip), %rbx     # 0x17320
cmpq %r14, %rbx
je 0x2ef4
movq 0x14536(%rip), %rsi     # 0x17320
addl $0xffff8ad0, %ebp       # imm = 0xFFFF8AD0
movb 0x144c3(%rip), %r8b     # 0x172ba
movzbl 0x14499(%rip), %eax     # 0x17297
movl %eax, 0x4(%rsp)
xorl %r15d, %r15d
movl 0x144c4(%rip), %r10d    # 0x172d0
xorl %edx, %edx
xorl %r13d, %r13d
xorl %r12d, %r12d
xorl %r9d, %r9d
cmpq %rsi, %rbx
jne 0x2e21
cmpq %r14, (%rbx)
je 0x2e2a
cmpl 0x14(%rbx), %ebp
js 0x2edf
movq 0x8(%rbx), %rdi
movq 0x8(%rdi), %r11
testq %r11, %r11
je 0x2edf
cmpl $0x0, 0x18(%rbx)
jne 0x2edf
cmpb $0x1, %r8b
jne 0x2ea0
movq %r9, 0x8(%rsp)
movl 0x34(%rdi), %ecx
movl %ecx, %r15d
shrl $0x2, %r15d
andl $0x20, %r15d
orl $0x40, %r15d
shrb $0x3, %cl
andb $0xf, %cl
shll %cl, %r15d
movzbl 0x19(%r11), %ecx
imull $0x64, %ecx, %eax
movl %edx, %r9d
xorl %edx, %edx
divl 0x4(%rsp)
movl %r9d, %edx
imull %eax, %eax
shrl $0x6, %r15d
imull %eax, %r15d
cmpl %r9d, %r15d
ja 0x2e9b
jne 0x2eed
cmpb %r13b, %cl
movq 0x8(%rsp), %r9
jbe 0x2ea8
movq %rbx, %r9
jmp 0x2ea8
cmpb %r13b, 0x19(%r11)
cmovaq %rbx, %r9
movl 0x34(%rdi), %eax
movzbl %r12b, %r12d
cmpb %r12b, %al
cmoval %eax, %r12d
movzbl 0x19(%r11), %eax
cmpb %r13b, %al
movzbl %r13b, %ecx
cmoval %eax, %ecx
cmpl %edx, %r15d
cmoval %r15d, %edx
movl %ecx, %r13d
testl %r10d, %r10d
je 0x2edf
movl (%rdi), %edi
cmpl %edi, %r10d
je 0x2fb6
movq (%rbx), %rbx
cmpq %r14, %rbx
jne 0x2e17
jmp 0x2eff
movq 0x8(%rsp), %r9
jmp 0x2ea8
xorl %r9d, %r9d
xorl %r12d, %r12d
xorl %r13d, %r13d
xorl %edx, %edx
movq 0x143ba(%rip), %rax     # 0x172c0
cmpq %r9, %rax
je 0x2fa0
testq %rax, %rax
je 0x2f44
testq %r9, %r9
leaq 0xca91(%rip), %rax      # 0xf9af
leaq 0xcafc(%rip), %rsi      # 0xfa21
cmoveq %rax, %rsi
movl $0x3, %edi
xorl %eax, %eax
movl %edx, %ebx
movq %r9, %r14
callq 0xd5b0
callq 0xb900
movq %r14, %r9
movl %ebx, %edx
movq %r9, 0x14375(%rip)      # 0x172c0
testq %r9, %r9
je 0x2fa0
movl %edx, %ebx
callq 0xb8e7
testb %al, %al
jne 0x2fa0
movq 0x1435e(%rip), %rax     # 0x172c0
movq 0x8(%rax), %rax
movl (%rax), %edi
leaq 0x10(%rsp), %r14
movq %r14, %rsi
movl $0x10, %edx
callq 0xb8b8
movzbl %r12b, %ecx
movzbl %r13b, %r8d
leaq 0xcac7(%rip), %rsi      # 0xfa50
movl $0x3, %edi
movq %r14, %rdx
movl %ebx, %r9d
xorl %eax, %eax
callq 0xd5b0
callq 0xb90f
xorl %edi, %edi
callq 0x689c
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 0xb8b8
movq 0x8(%rbx), %rax
movzbl 0x34(%rax), %ecx
movq 0x8(%rax), %rax
movzbl 0x19(%rax), %r8d
leaq 0xc9fb(%rip), %rsi      # 0xf9dd
movl $0x3, %edi
movq %r14, %rdx
movl %r15d, %r9d
xorl %eax, %eax
callq 0xd5b0
movl %ebp, %edx
movq %rbx, %r9
jmp 0x2eff