#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>
#include <errno.h>
#include <unistd.h>
#include "agentapi.h"
#include "debug.h"
#include "util.h"
#include "dyn_ip.h"
#include "mn.h"
#include "monitor.h"
#include "fixed_fd_zero.h"
Include dependency graph for mn.c:
Go to the source code of this file.
Functions | |
int | degrade_current_fa_priority (void) |
void | passive_find (void) |
void | find_agent (int entry) |
find_agent: - STATE_INIT to move to this state STATE_TIMEOUT to indicate timeout in this state, ie. | |
void | request_tunnel (int entry, int forced, int check_timer) |
rqeuest_tunnel: : STATE_INIT to move to this state, STATE_TIMEOUT to indicate timeout in this state, i.e. | |
void | connected (int type, __u16 lifetime) |
void | close_for_home (int entry) |
void | at_home (void) |
void | disconnect (void) |
int | main_vanha (int argc, char *argv[]) |
Variables | |
int | real_tunnel_up |
mn_data | mn |
mn_config | config |
timeval | timers [TIMER_COUNT] |
char * | program_name |
void at_home | ( | void | ) |
Definition at line 730 of file mn.c.
References DEBUG(), DEBUG_INFO, DEBUG_STATES, DEBUG_TIMERS, mn, MN_AT_HOME, mn_remove_dynamic_home_addr(), send_gratuitous_arp(), mn_data::state, TIMER_GEN, and timers.
Referenced by close_for_home(), and main_vanha().
00731 { 00732 DEBUG(DEBUG_INFO, "at_home()\n"); 00733 send_gratuitous_arp(config.ha_ip_addr, config.mn_home_ip_addr); 00734 mn.state = MN_AT_HOME; 00735 DEBUG(DEBUG_STATES, "State: At home\n"); 00736 DEBUG(DEBUG_TIMERS, "Clearing TIMER_GEN\n"); 00737 timerclear(&timers[TIMER_GEN]); 00738 mn_remove_dynamic_home_addr(); 00739 }
Here is the call graph for this function:
void close_for_home | ( | int | entry | ) |
Definition at line 649 of file mn.c.
References agentadv_data::addr, at_home(), mn_data::co_addr, mn_data::current_adv, DEBUG(), DEBUG_INFO, DEBUG_MESSAGES, DEBUG_STATES, DEBUG_TIMERS, mn_data::fa_addr, mn_data::HA_reg_retry_time, mn_data::local_addr, LOG2, MAX_REGISTRATION_TIME, MIN_REGISTRATION_TIME, mn, MN_CLOSE_FOR_HOME, real_tunnel_up, REG_DISC, agentadv_data::reg_retry_time, send_gratuitous_arp(), send_registration(), mn_data::session_key, mn_data::session_key_len, mn_config::shared_secret_len, mn_data::state, STATE_INIT, stop_tunneling(), TIMER_GEN, and timers.
00650 { 00651 int retry_time; 00652 00653 DEBUG(DEBUG_INFO, "close_for_home(%i)\n", entry); 00654 00655 if (mn.current_adv == NULL) { 00656 LOG2(LOG_ALERT, "close_for_home - current_adv == NULL\n"); 00657 } 00658 if (entry == STATE_INIT) { 00659 mn.state = MN_CLOSE_FOR_HOME; 00660 if (real_tunnel_up) 00661 stop_tunneling(); 00662 else if (config.shared_secret_len < 0 || 00663 config.mn_home_ip_addr.s_addr == 0) { 00664 DEBUG(DEBUG_INFO, 00665 "close_for_home - not registered; going directly" 00666 " to home\n"); 00667 at_home(); 00668 return; 00669 } else { 00670 DEBUG(DEBUG_INFO, 00671 "close_for_home - not registered, but trying to " 00672 "deregister possible old bindings at HA\n"); 00673 if (mn.co_addr.s_addr == 0) 00674 mn.co_addr.s_addr = mn.local_addr.s_addr; 00675 } 00676 if (mn.current_adv != NULL) { 00677 DEBUG(DEBUG_TIMERS, "FA[%s] reg_retry_time: " 00678 "%i => %i (close_for_home)\n", 00679 inet_ntoa(mn.current_adv->addr), 00680 mn.current_adv->reg_retry_time, 00681 MIN_REGISTRATION_TIME); 00682 mn.current_adv->reg_retry_time = MIN_REGISTRATION_TIME; 00683 } else 00684 mn.HA_reg_retry_time = MIN_REGISTRATION_TIME; 00685 00686 /* drop the previous session key so that locupd to FA with the 00687 * old binding goes to the HA */ 00688 if (mn.session_key != NULL) 00689 free(mn.session_key); 00690 mn.session_key = NULL; 00691 mn.session_key_len = 0; 00692 } else if (mn.current_adv == NULL || 00693 mn.current_adv->reg_retry_time >= MAX_REGISTRATION_TIME) { 00694 DEBUG(DEBUG_MESSAGES, 00695 "Could not get reply from HA - assuming deregistration " 00696 "worked\n"); 00697 at_home(); 00698 return; 00699 } else if (mn.current_adv != NULL) { 00700 DEBUG(DEBUG_TIMERS, "FA[%s] reg_retry_time: %i => ", 00701 inet_ntoa(mn.current_adv->addr), 00702 mn.current_adv->reg_retry_time); 00703 if (mn.current_adv->reg_retry_time == 0) 00704 mn.current_adv->reg_retry_time = 1; 00705 else 00706 mn.current_adv->reg_retry_time *= 2; 00707 DEBUG(DEBUG_TIMERS, "%i\n", mn.current_adv->reg_retry_time); 00708 } 00709 00710 send_gratuitous_arp(config.ha_ip_addr, config.mn_home_ip_addr); 00711 00712 /* send deregistration message to HA */ 00713 mn.fa_addr = config.ha_ip_addr; 00714 send_registration(REG_DISC); 00715 00716 /* at least full retry time should be waited */ 00717 gettimeofday(&timers[TIMER_GEN], NULL); 00718 retry_time = mn.current_adv ? mn.current_adv->reg_retry_time : 00719 mn.HA_reg_retry_time; 00720 DEBUG(DEBUG_TIMERS, "close_for_home - TIMER_GEN: set now+%i sec\n", 00721 retry_time); 00722 timers[TIMER_GEN].tv_sec += retry_time; 00723 00724 DEBUG(DEBUG_STATES, "State: Close for home\n"); 00725 }
Here is the call graph for this function:
void connected | ( | int | type, | |
__u16 | lifetime | |||
) |
Definition at line 513 of file mn.c.
References agentadv_data::addr, ASSERT, CON_HA, mn_data::current_adv, DEBUG(), DEBUG_INFO, DEBUG_STATES, DEBUG_TIMERS, mn_config::enable_fa_decapsulation, mn_data::fa_addr, agentadv_data::in_use, mn_data::info_str, LOG2, mn, MN_CONNECTED, mn_config::mn_default_tunnel_lifetime, agentadv_data::prio_degrade_percent, real_tunnel_up, remove_fa_host_routes(), restart_tunneling(), start_tunneling(), mn_data::state, TIMER_GEN, TIMER_LIFETIME, TIMER_REQUEST, TIMER_REREG, timers, mn_data::tunnel_addr, mn_data::tunnel_up, and mn_data::warn_str.
00514 { 00515 DEBUG(DEBUG_INFO, "connected(%i, %i)\n", type, lifetime); 00516 ASSERT(lifetime > 0); 00517 00518 if (mn.current_adv != NULL) { 00519 if (mn.current_adv->addr.s_addr != mn.fa_addr.s_addr) { 00520 DEBUG(DEBUG_INFO, "fa_addr=%s != ", 00521 inet_ntoa(mn.fa_addr)); 00522 DEBUG(DEBUG_INFO, "current_adv->addr=%s\n", 00523 inet_ntoa(mn.current_adv->addr)); 00524 } 00525 mn.current_adv->in_use = 1; 00526 /* This FA works, so don't degrade priority: */ 00527 mn.current_adv->prio_degrade_percent = 0; 00528 } else { 00529 LOG2(LOG_WARNING, "connected - current_adv == NULL\n"); 00530 mn.warn_str = "connected - current_adv == NULL"; 00531 } 00532 00533 /* HA MUST NOT use larger lifetime and the FAs cannot change the 00534 * requested lifetime - force the lifetime to be at maximum the 00535 * configured time */ 00536 if (lifetime > config.mn_default_tunnel_lifetime) { 00537 LOG2(LOG_WARNING, "Lifetime in the reply (%i sec) larger than " 00538 "expected (%i sec) - lowering it\n", lifetime, 00539 config.mn_default_tunnel_lifetime); 00540 mn.warn_str = "lifetime in the reply larger than expected"; 00541 lifetime = config.mn_default_tunnel_lifetime; 00542 } 00543 00544 if (config.enable_fa_decapsulation && 00545 mn.fa_addr.s_addr != mn.tunnel_addr.s_addr && 00546 mn.tunnel_addr.s_addr != 0 && 00547 mn.current_adv != NULL) 00548 remove_fa_host_routes(0); 00549 00550 /* if tunnel endpoint has changed, or tunnel is down, create tunnel to 00551 * FA */ 00552 if (mn.fa_addr.s_addr != mn.tunnel_addr.s_addr || !real_tunnel_up) { 00553 if (real_tunnel_up) { 00554 DEBUG(DEBUG_STATES, "Restart tunneling\n"); 00555 restart_tunneling(); 00556 } else { 00557 DEBUG(DEBUG_STATES, "Start tunneling\n"); 00558 start_tunneling(); 00559 } 00560 } 00561 00562 /* set lifetime timer */ 00563 timers[TIMER_LIFETIME].tv_sec = timers[TIMER_REQUEST].tv_sec + 00564 lifetime; 00565 timers[TIMER_LIFETIME].tv_usec = timers[TIMER_REQUEST].tv_usec; 00566 00567 /* If connection was approved by HA, 00568 * reset timer for reregistering the tunnel */ 00569 if (type == CON_HA) { 00570 set_reregistration_time(lifetime); 00571 } 00572 if (mn.state != MN_CONNECTED && type == CON_HA) { 00573 LOG2(LOG_INFO, "Connection established.\n"); 00574 mn.info_str = "connection established"; 00575 } 00576 00577 DEBUG(DEBUG_TIMERS, "setting TIMER_GEN = TIMER_REREG %li.%06li (in %li" 00578 " sec)\n", 00579 timers[TIMER_REREG].tv_sec, timers[TIMER_REREG].tv_usec, 00580 timers[TIMER_REREG].tv_sec - time(NULL)); 00581 timers[TIMER_GEN] = timers[TIMER_REREG]; 00582 mn.state = MN_CONNECTED; 00583 mn.tunnel_up = 1; 00584 DEBUG(DEBUG_STATES, "State: Connected\n"); 00585 }
Here is the call graph for this function:
int degrade_current_fa_priority | ( | void | ) |
Definition at line 80 of file mn.c.
References mn_data::current_adv, DEBUG(), DEBUG_INFO, DEFAULT_PRIO_DEGRADE_FACTOR, DEFAULT_PRIO_DEGRADE_INITIAL, mn, and agentadv_data::prio_degrade_percent.
Referenced by request_tunnel().
00081 { 00082 if (mn.current_adv == NULL) 00083 return 1; 00084 00085 if (mn.current_adv->prio_degrade_percent == 0) { 00086 mn.current_adv->prio_degrade_percent = 00087 DEFAULT_PRIO_DEGRADE_INITIAL; 00088 } else { 00089 mn.current_adv->prio_degrade_percent *= 00090 DEFAULT_PRIO_DEGRADE_FACTOR; 00091 } 00092 00093 if (mn.current_adv->prio_degrade_percent > 100) { 00094 mn.current_adv->prio_degrade_percent = 100; 00095 } 00096 00097 DEBUG(DEBUG_INFO, "degrade_current_fa_priority: %d\n", 00098 mn.current_adv->prio_degrade_percent); 00099 00100 return 0; 00101 }
Here is the call graph for this function:
void disconnect | ( | void | ) |
Definition at line 744 of file mn.c.
References mn_data::cur_route_info, DEBUG(), DEBUG_INFO, DEBUG_MESSAGES, DEBUG_STATES, DEBUG_TIMERS, mn, MN_CONNECTED, MN_DISCONNECTED, mn_remove_dynamic_home_addr(), real_tunnel_up, REG_DISC, send_registration(), mn_data::session_key, mn_data::session_key_len, mn_data::state, stop_tunneling(), TIMER_GEN, and timers.
Referenced by handle_api().
00745 { 00746 DEBUG(DEBUG_INFO, "disconnect()\n"); 00747 00748 mn.cur_route_info.known = 0; 00749 00750 /* if we are connected, we'd better throw out a 00751 * deregistration message */ 00752 if (mn.state == MN_CONNECTED) { 00753 send_registration(REG_DISC); 00754 DEBUG(DEBUG_MESSAGES, "Deregistration message sent\n"); 00755 } 00756 if (real_tunnel_up) stop_tunneling(); 00757 00758 /* free session key */ 00759 if (mn.session_key) { 00760 free(mn.session_key); 00761 mn.session_key = NULL; 00762 mn.session_key_len = 0; 00763 } 00764 00765 DEBUG(DEBUG_TIMERS, "Clearing TIMER_GEN\n"); 00766 timerclear(&timers[TIMER_GEN]); 00767 mn.state = MN_DISCONNECTED; 00768 DEBUG(DEBUG_STATES, "State: Disconnected\n"); 00769 syslog(LOG_INFO, "Disconnected."); 00770 mn_remove_dynamic_home_addr(); 00771 }
Here is the call graph for this function:
void find_agent | ( | int | entry | ) |
find_agent: - STATE_INIT to move to this state STATE_TIMEOUT to indicate timeout in this state, ie.
we haven't received an agent adv to our last sent solicitation
Enter find agent state
Definition at line 308 of file mn.c.
References mn_data::co_addr, mn_data::current_adv, DEBUG(), DEBUG_INFO, DEBUG_STATES, DEBUG_TIMERS, mn_data::device_count, mn_data::fa_addr, FA_GET_NO, get_fa(), mn_config::home_net_addr_plen, mn_config::home_net_subnet_bc, agentadv_data::in_use, mn_data::local_addr, MAX_RANDOM_SOLICITATION_DELAY, mn, mn_config::mn_default_tunnel_lifetime, MN_FIND_AGENT, passive_find(), mn_data::req_lifetime, request_tunnel(), mn_data::state, STATE_INIT, TIMER_GEN, timers, mn_data::tunnel_mode, and mn_data::tunnel_up.
Referenced by handle_api(), main_vanha(), and request_tunnel().
00309 { 00310 int t, chg; 00311 static int retry_time = 0; /* time in seconds between retries of agent 00312 * solicitations */ 00313 00314 DEBUG(DEBUG_INFO, "find_agent(%i)\n", entry); 00315 00316 mn.tunnel_up = 0; 00317 00318 if (mn.device_count == 0) { 00319 passive_find(); 00320 return; 00321 } 00322 00323 if (mn.tunnel_mode == API_TUNNEL_FULL_HA) { 00324 DEBUG(DEBUG_INFO, 00325 "find_agent: trying to register directly to HA\n"); 00326 if (config.ha_ip_addr.s_addr == 0 && 00327 config.home_net_addr_plen > -1) { 00328 /* dynamic HA address resolution */ 00329 mn.fa_addr.s_addr = config.home_net_subnet_bc.s_addr; 00330 } else 00331 mn.fa_addr.s_addr = config.ha_ip_addr.s_addr; 00332 mn.co_addr.s_addr = mn.local_addr.s_addr; 00333 if (mn.current_adv != NULL) { 00334 mn.current_adv->in_use = 0; 00335 mn.current_adv = NULL; 00336 } 00337 request_tunnel(STATE_INIT, 0, 0); 00338 return; 00339 } 00340 00341 /* try to find the best FA from the previously received agentadvs; 00342 * if a valid entry is found, use it; otherwise send agent 00343 * solicitation */ 00344 chg = get_fa(NULL); 00345 if (chg != FA_GET_NO) { 00346 DEBUG(DEBUG_INFO, "find_agent: found FA from stored agentadv " 00347 "data - FA=%s, HFA=", inet_ntoa(mn.fa_addr)); 00348 DEBUG(DEBUG_INFO, "%s\n", inet_ntoa(mn.co_addr)); 00349 request_tunnel(STATE_INIT, 0, 0); 00350 return; 00351 } 00352 00353 if (entry == STATE_INIT) { 00354 mn.state = MN_FIND_AGENT; 00355 retry_time = 0; 00356 mn.req_lifetime = config.mn_default_tunnel_lifetime; 00357 } 00358 00359 t = get_solicitation_interval(&retry_time); 00360 if (t == 0) { 00361 passive_find(); 00362 return; 00363 } 00364 00365 /* send agent solicitation to all the active interfaces */ 00366 send_solicitations(&mn); 00367 00368 DEBUG(DEBUG_TIMERS, "find_agent - TIMER_GEN: set now+%i sec\n", t); 00369 gettimeofday(&timers[TIMER_GEN], NULL); 00370 timers[TIMER_GEN].tv_sec += t; 00371 add_usecs(&timers[TIMER_GEN], 00372 get_rand32() % MAX_RANDOM_SOLICITATION_DELAY); 00373 00374 DEBUG(DEBUG_STATES, "State: Find agent\n"); 00375 }
Here is the call graph for this function:
int main_vanha | ( | int | argc, | |
char * | argv[] | |||
) |
Definition at line 910 of file mn.c.
References at_home(), check_expired_agent_advs(), check_interfaces(), check_old_tunnel_expiration(), mn_config::enable_fa_decapsulation, mn_config::enforce_routes, find_agent(), handle_api(), handle_icmp(), handle_registration(), is_coloc_addr_foreign(), LOG2, mn, MN_DISCONNECTED, mn_init(), mn_parse_command_line(), MN_STOP, program_name, and STATE_INIT.
00911 { 00912 int n, i; 00913 fd_set set; 00914 struct timeval tv; 00915 00916 memset(&mn, 0, sizeof(mn)); 00917 mn.info_str = "initialization in progress"; 00918 00919 program_name = parse_long_options(argc, argv, "mobile node", 00920 PACKAGE, VERSION, dynamics_usage); 00921 00922 mn_parse_command_line(argc, argv); 00923 00924 if (!mn_init()) { 00925 fprintf(stderr, "Initialization failed.\n"); 00926 exit(0); 00927 } 00928 00929 if (mn.opt_connect) { 00930 /* try to connect to a FA if MN is using FA decapsulation (i.e. 00931 * its own home IP addr also in the foreign network) or if the 00932 * home address is not assigned to a local interface with MN 00933 * decapsulation */ 00934 mn.info_str = "trying to connect"; 00935 if (config.enable_fa_decapsulation || is_coloc_addr_foreign()) 00936 { 00937 mn.tunnel_mode = API_TUNNEL_FULL; 00938 find_agent(STATE_INIT); 00939 } else at_home(); 00940 } 00941 00942 /* MN main loop */ 00943 while (mn.state != MN_STOP) { 00944 check_old_tunnel_expiration(); 00945 00946 FD_ZERO(&set); 00947 FD_SET(mn.registration_socket, &set); 00948 for (i = 0; i < MAX_INTERFACES; i++) { 00949 if (mn.iface[i].s_adv > -1) 00950 FD_SET(mn.iface[i].s_adv, &set); 00951 } 00952 if (mn.api_rw_socket > -1) 00953 FD_SET(mn.api_rw_socket, &set); 00954 if (mn.api_ro_socket > -1) 00955 FD_SET(mn.api_ro_socket, &set); 00956 #ifdef INCLUDE_IPAY 00957 FD_SET(mn.ipay_sock, &set); 00958 FD_SET(mn.ipay_sock_fa, &set); 00959 #endif 00960 if (mn.rtnetlink_socket > -1) 00961 FD_SET(mn.rtnetlink_socket, &set); 00962 00963 if (get_next_timeout(&tv)) 00964 n = select(FD_SETSIZE, &set, NULL, NULL, &tv); 00965 else n = select(FD_SETSIZE, &set, NULL, NULL, NULL); 00966 if (n == 0) { 00967 handle_timeout(); 00968 continue; 00969 } else if (n == -1) { 00970 switch (errno) { 00971 case EINTR: 00972 break; 00973 default: 00974 LOG2(LOG_ERR, "main - select: %s\n", 00975 strerror(errno)); 00976 /* this used to exit dynmnd with 00977 * mn.state = MN_STOP; 00978 * but this might be a temporary problem, so 00979 * try agains; use a small delay to prevent 00980 * hogging all the CPU in case of select() 00981 * returning error all the time */ 00982 sleep(1); 00983 } 00984 continue; 00985 } 00986 00987 if (FD_ISSET(mn.registration_socket, &set) && 00988 handle_registration(mn.registration_socket)) { 00989 /* try to reregister */ 00990 reinitiate_state(); 00991 } 00992 00993 for (i = 0; i < MAX_INTERFACES; i++) { 00994 if (mn.iface[i].s_adv > -1 && 00995 FD_ISSET(mn.iface[i].s_adv, &set)) 00996 handle_icmp(&mn.iface[i]); 00997 } 00998 00999 if (mn.rtnetlink_socket > -1 && 01000 FD_ISSET(mn.rtnetlink_socket, &set)) { 01001 int res = dyn_ip_monitor_get( 01002 mn.rtnetlink_socket, 01003 (config.enforce_routes && 01004 mn.state != MN_DISCONNECTED) ? 01005 &mn.cur_route_info : NULL); 01006 if (res == 1 || res == 2) 01007 check_interfaces(mn.iface, MAX_INTERFACES); 01008 } 01009 01010 if (mn.api_rw_socket > -1 && FD_ISSET(mn.api_rw_socket, &set)) 01011 handle_api(mn.api_rw_socket, 1); 01012 01013 if (mn.api_ro_socket > -1 && FD_ISSET(mn.api_ro_socket, &set)) 01014 handle_api(mn.api_ro_socket, 0); 01015 01016 #ifdef INCLUDE_IPAY 01017 if (FD_ISSET(mn.ipay_sock, &set)) 01018 handle_ipay(mn.ipay_sock); 01019 if (FD_ISSET(mn.ipay_sock_fa, &set)) 01020 handle_ipay(mn.ipay_sock_fa); 01021 #endif 01022 01023 /* check expired agent advs. If current FA's agent 01024 adv. has expired move to FIND_AGENT state */ 01025 if (check_expired_agent_advs()) 01026 find_agent(STATE_INIT); 01027 } 01028 01029 clean_up(0); 01030 return 0; 01031 }
Here is the call graph for this function:
void passive_find | ( | void | ) |
Definition at line 268 of file mn.c.
References DEBUG(), DEBUG_STATES, mn, MN_PASSIVE_FIND, and mn_data::state.
Referenced by find_agent().
00269 { 00270 mn.state = MN_PASSIVE_FIND; 00271 DEBUG(DEBUG_STATES, "State: Passive find\n"); 00272 }
Here is the call graph for this function:
void request_tunnel | ( | int | entry, | |
int | forced, | |||
int | check_timer | |||
) |
rqeuest_tunnel: : STATE_INIT to move to this state, STATE_TIMEOUT to indicate timeout in this state, i.e.
no reply for last request within retry time
Enter request tunnel state
Definition at line 386 of file mn.c.
References add_fa_host_route(), agentadv_data::addr, mn_data::agentadv, mn_data::current_adv, DEBUG(), DEBUG_INFO, DEBUG_STATES, DEBUG_TIMERS, degrade_current_fa_priority(), mn_config::enable_fa_decapsulation, mn_data::fa_addr, find_agent(), mn_data::HA_reg_retry_time, agentadv_data::ifindex, agentadv_data::ifname, mn_data::info_str, mn_data::last_reg_send_time, MAX_REGISTRATION_TIME, MIN_REGISTRATION_DELAY, MIN_REGISTRATION_TIME, mn, MN_REQUEST_TUNNEL, REG_CONNECT, REG_REREG, agentadv_data::reg_retry_time, reply_waiting_api(), send_registration(), mn_data::state, STATE_INIT, TIMER_GEN, timers, mn_data::tunnel_up, mn_config::use_hadisc, and mn_data::warn_str.
Referenced by find_agent(), and handle_api().
00387 { 00388 int retry_time; 00389 00390 DEBUG(DEBUG_INFO, "request_tunnel(%i, %i, %i)\n", entry, forced, 00391 check_timer); 00392 00393 if (mn.current_adv == NULL) { 00394 retry_time = mn.HA_reg_retry_time; 00395 DEBUG(DEBUG_INFO, "No current agent advertisement " 00396 "when requesting tunnel (direct tunnel to HA?)\n"); 00397 } else 00398 retry_time = mn.current_adv->reg_retry_time; 00399 00400 if (check_timer && retry_time > 1) { 00401 struct timeval now; 00402 gettimeofday(&now, NULL); 00403 if (timerisset(&timers[TIMER_GEN]) && 00404 cmp_timeval(&now, &timers[TIMER_GEN]) < 0) { 00405 DEBUG(DEBUG_TIMERS, "request_tunnel: TIMER_GEN not " 00406 "yet reached\n"); 00407 return; 00408 } 00409 } 00410 00411 if (config.enable_fa_decapsulation && mn.current_adv != NULL) 00412 add_fa_host_route(mn.current_adv->ifname, mn.agentadv, 00413 mn.current_adv->ifindex, mn.fa_addr); 00414 00415 if (entry == STATE_INIT) { 00416 mn.state = MN_REQUEST_TUNNEL; 00417 if (!forced) 00418 mn.tunnel_up = 0; 00419 00420 /* if last registration was sent less than a second ago, 00421 wait a second before sending the request */ 00422 if (usec_passed(&mn.last_reg_send_time, NULL) < 00423 MIN_REGISTRATION_DELAY) { 00424 DEBUG(DEBUG_INFO, "Too frequent registration request " 00425 "- delaying\n"); 00426 DEBUG(DEBUG_TIMERS, "request_tunnel: TIMER_GEN: set " 00427 "now+1 sec (too freq.)\n"); 00428 gettimeofday(&timers[TIMER_GEN], NULL); 00429 timers[TIMER_GEN].tv_sec++; 00430 return; 00431 } 00432 } else if (retry_time > MAX_REGISTRATION_TIME) { 00433 /* STATE_TIMEOUT */ 00434 if (config.use_hadisc) { 00435 DEBUG(DEBUG_INFO, "HA does not reply - try to discover" 00436 " another HA\n"); 00437 mn.info_str = "restarting HA discovery"; 00438 config.ha_ip_addr.s_addr = 0; 00439 if (mn.current_adv != NULL) 00440 mn.current_adv->reg_retry_time = 00441 MIN_REGISTRATION_TIME; 00442 else 00443 mn.HA_reg_retry_time = 00444 MIN_REGISTRATION_TIME; 00445 } else { 00446 /* give up, switch to find agent */ 00447 if (forced) { 00448 DEBUG(DEBUG_INFO, 00449 "Could not confirm tunnel.\n"); 00450 reply_waiting_api(API_FAILED, NULL, 0); 00451 } else { 00452 DEBUG(DEBUG_INFO, "Could not register.\n"); 00453 } 00454 find_agent(STATE_INIT); 00455 return; 00456 } 00457 } else if (mn.current_adv != NULL) { 00458 /* STATE_TIMEOUT */ 00459 #ifndef NO_PRIO_DEGRADE 00460 /* degrade the FA priority */ 00461 degrade_current_fa_priority(); 00462 #endif /* NO_PRIO_DEGRADE */ 00463 DEBUG(DEBUG_TIMERS, "FA[%s] reg_retry_time: %i => ", 00464 inet_ntoa(mn.current_adv->addr), 00465 mn.current_adv->reg_retry_time); 00466 if (mn.current_adv->reg_retry_time == 0) 00467 mn.current_adv->reg_retry_time = MIN_REGISTRATION_TIME; 00468 else 00469 mn.current_adv->reg_retry_time *= 2; 00470 DEBUG(DEBUG_TIMERS, "%i\n", mn.current_adv->reg_retry_time); 00471 } else { 00472 if (mn.HA_reg_retry_time == 0) 00473 mn.HA_reg_retry_time = MIN_REGISTRATION_TIME; 00474 else 00475 mn.HA_reg_retry_time *= 2; 00476 } 00477 00478 if (send_registration(forced ? REG_REREG : REG_CONNECT) < 0) { 00479 DEBUG(DEBUG_INFO, "Registration failed for this FA - trying to" 00480 " find a new one\n"); 00481 mn.warn_str = "Registration failed for this FA, trying to find" 00482 " a new one"; 00483 find_agent(STATE_INIT); 00484 return; 00485 } 00486 00487 gettimeofday(&timers[TIMER_GEN], NULL); 00488 if (mn.current_adv != NULL) { 00489 if (mn.current_adv->reg_retry_time < MIN_REGISTRATION_TIME) 00490 mn.current_adv->reg_retry_time = MIN_REGISTRATION_TIME; 00491 retry_time = mn.current_adv->reg_retry_time; 00492 } else { 00493 if (mn.HA_reg_retry_time < MIN_REGISTRATION_TIME) 00494 mn.HA_reg_retry_time = MIN_REGISTRATION_TIME; 00495 retry_time = mn.HA_reg_retry_time; 00496 } 00497 DEBUG(DEBUG_TIMERS, "request_tunnel - TIMER_GEN: set now+%i sec\n", 00498 retry_time); 00499 timers[TIMER_GEN].tv_sec += retry_time; 00500 00501 DEBUG(DEBUG_STATES, "State: Request tunnel%s\n", 00502 forced ? " (forced)" : ""); 00503 }
Here is the call graph for this function:
Definition at line 44 of file mn.c.
Referenced by adv_ok_fa(), at_home(), check_expired_agent_advs(), clean_agentadv(), clean_up(), close_for_home(), connected(), create_mobile(), degrade_current_fa_priority(), device_up(), disconnect(), find_agent(), get_fa(), handle_api(), handle_icmp(), handle_registration(), load_mn(), main_vanha(), mn_init(), mn_parse_command_line(), mn_remove_dynamic_home_addr(), monitor_poll_ap_addresses(), passive_find(), remove_fa_host_routes(), reply_waiting_api(), request_tunnel(), restart_tunneling(), send_registration(), start_tunneling(), stop_tunneling(), and update_fa_decaps_routes().
char* program_name |
int real_tunnel_up |
Definition at line 30 of file mn_tunnel.c.
Referenced by close_for_home(), close_tunneling(), connected(), disconnect(), init_tunneling(), restart_tunneling(), start_tunneling(), and stop_tunneling().
struct timeval timers[TIMER_COUNT] |
Definition at line 47 of file mn.c.
Referenced by at_home(), close_for_home(), connected(), disconnect(), find_agent(), mn_init(), request_tunnel(), and send_registration().