// File: /workspace/github_c_makefile_star2_O2/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 $0x48, %rsp
xorl %edi, %edi
callq 0x63a8
callq 0xa9e4
movl %eax, %ebp
movb 0x146c2(%rip), %al      # 0x172ba
testb %al, %al
je 0x2c50
cmpb $0x3, %al
ja 0x2c1d
callq 0xaa72
movswq 0x1467d(%rip), %rcx     # 0x1728a
movzbl 0x14683(%rip), %edx     # 0x17297
imulq %rcx, %rdx
cmpq %rdx, %rax
js 0x2c50
leaq 0x146fc(%rip), %r14     # 0x17320
movq %r14, %rdi
callq 0x5778
testl %eax, %eax
je 0x2c65
cmpq $0x0, 0x14688(%rip)     # 0x172c0
je 0x2c50
leaq 0xbd6e(%rip), %rsi      # 0xe9af
pushq $0x3
popq %rdi
xorl %eax, %eax
callq 0xcb1c
callq 0xb095
xorl %edi, %edi
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x63c4
movq 0x146b4(%rip), %r15     # 0x17320
addl $0xffff8ad0, %ebp       # imm = 0xFFFF8AD0
movb 0x14641(%rip), %r9b     # 0x172ba
movzbl 0x14617(%rip), %eax     # 0x17297
movl %eax, 0x10(%rsp)
movl 0x14646(%rip), %edi     # 0x172d0
movq %r15, %rbx
xorl %r10d, %r10d
xorl %r12d, %r12d
xorl %edx, %edx
xorl %r8d, %r8d
xorl %eax, %eax
movq %r14, %rsi
movl %edi, 0x8(%rsp)
movb %r9b, 0x6(%rsp)
cmpq %rsi, %rbx
je 0x2dec
cmpq %r15, %rbx
jne 0x2cb9
cmpq %rsi, (%rbx)
je 0x2cc2
cmpl 0x14(%rbx), %ebp
js 0x2d9f
movq 0x8(%rbx), %r13
movq 0x8(%r13), %r14
testq %r14, %r14
je 0x2d9f
cmpl $0x0, 0x18(%rbx)
jne 0x2d9f
cmpb $0x1, %r9b
jne 0x2d5d
movq %r10, 0x18(%rsp)
movq %rdx, 0x20(%rsp)
movl %r12d, 0xc(%rsp)
movb 0x34(%r13), %al
movb %al, 0x7(%rsp)
movzbl %al, %edi
leaq 0x14(%rsp), %rsi
leaq 0x2c(%rsp), %rdx
movl %r8d, %r12d
callq 0x2ef8
movl %r12d, %r8d
movzbl 0x19(%r14), %ecx
imull $0x64, %ecx, %eax
xorl %edx, %edx
divw 0x10(%rsp)
movzwl %ax, %esi
imull %esi, %esi
movl 0x14(%rsp), %eax
cltd
pushq $0x40
popq %rdi
idivl %edi
imull %esi, %eax
cmpl %r12d, %eax
jbe 0x2da7
movq %rbx, %r10
movl 0xc(%rsp), %r12d
movq 0x20(%rsp), %rdx
leaq 0x145d3(%rip), %rsi     # 0x17320
movl 0x8(%rsp), %edi
movb 0x6(%rsp), %r9b
movb 0x7(%rsp), %r11b
jmp 0x2d6b
movb 0x19(%r14), %cl
cmpb %dl, %cl
cmovaq %rbx, %r10
movb 0x34(%r13), %r11b
movzbl %r11b, %r11d
movzbl %r12b, %r12d
cmpb %r12b, %r11b
cmoval %r11d, %r12d
movzbl %cl, %r11d
cmpb %dl, %r11b
movzbl %dl, %ecx
cmoval %r11d, %ecx
cmpl %r8d, %eax
cmoval %eax, %r8d
movl %ecx, %edx
testl %edi, %edi
je 0x2d9f
cmpl (%r13), %edi
je 0x2eac
movq (%rbx), %rbx
jmp 0x2ca6
movl 0xc(%rsp), %r12d
movq 0x20(%rsp), %rdx
movl 0x8(%rsp), %edi
jne 0x2dd6
cmpb %dl, %cl
leaq 0x14560(%rip), %rsi     # 0x17320
movb 0x6(%rsp), %r9b
movq 0x18(%rsp), %r10
movb 0x7(%rsp), %r11b
jbe 0x2d6b
movq %rbx, %r10
jmp 0x2d6b
leaq 0x14543(%rip), %rsi     # 0x17320
movb 0x6(%rsp), %r9b
movq 0x18(%rsp), %r10
jmp 0x2d56
movq %r10, %rbx
movq 0x144ca(%rip), %rax     # 0x172c0
cmpq %rbx, %rax
je 0x2e96
testq %rax, %rax
je 0x2e34
testq %rbx, %rbx
leaq 0xbba1(%rip), %rax      # 0xe9af
leaq 0xbc0c(%rip), %rsi      # 0xea21
cmoveq %rax, %rsi
pushq $0x3
popq %rdi
xorl %eax, %eax
movl %r8d, %ebp
movq %rdx, %r14
callq 0xcb1c
callq 0xb095
movq %r14, %rdx
movl %ebp, %r8d
movq %rbx, 0x14485(%rip)     # 0x172c0
testq %rbx, %rbx
je 0x2e96
movl %r8d, %ebx
movq %rdx, %r14
callq 0xb07c
testb %al, %al
jne 0x2e96
movq %r14, %rcx
movq 0x14467(%rip), %rax     # 0x172c0
movq 0x8(%rax), %rax
movl (%rax), %edi
leaq 0x30(%rsp), %r14
movq %rcx, %r15
pushq $0x10
popq %rdx
movq %r14, %rsi
callq 0xb04f
movzbl %r12b, %ecx
movzbl %r15b, %r8d
leaq 0xbbcf(%rip), %rsi      # 0xea50
pushq $0x3
popq %rdi
movq %r14, %rdx
movl %ebx, %r9d
xorl %eax, %eax
callq 0xcb1c
callq 0xb0a1
xorl %edi, %edi
callq 0x63c4
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x30(%rsp), %r14
movq %rdx, %r15
pushq $0x10
popq %rdx
movq %r14, %rsi
movl %r8d, %ebp
movl %eax, %r13d
callq 0xb04f
movq 0x8(%rbx), %rax
movzbl 0x34(%rax), %ecx
movq 0x8(%rax), %rax
movzbl 0x19(%rax), %r8d
leaq 0xbb00(%rip), %rsi      # 0xe9dd
pushq $0x3
popq %rdi
movq %r14, %rdx
movl %r13d, %r9d
xorl %eax, %eax
callq 0xcb1c
movq %r15, %rdx
movl %ebp, %r8d
jmp 0x2def