int pkb_check_frontend_dns(struct pk_manager* pkm) { int i, changes, have_nulls; time_t obsolete; struct pk_tunnel* fe; char* last_fe_hostname; PK_TRACE_FUNCTION; /* Walk through frontend list, look each up in DNS and add new entries * as necessary. */ changes = 0; have_nulls = 0; last_fe_hostname = ""; for (i = 0, fe = pkm->tunnels; i < pkm->tunnel_max; i++, fe++) { if ((fe->fe_hostname != NULL) && (0 != strcmp(fe->fe_hostname, last_fe_hostname))) { pk_log(PK_LOG_MANAGER_DEBUG, "Checking for new IPs: %s", fe->fe_hostname); changes += pkm_add_frontend(pkm, fe->fe_hostname, fe->fe_port, 0); last_fe_hostname = fe->fe_hostname; } if ((fe->fe_hostname != NULL) && (fe->ai.ai_addr == NULL)) { have_nulls += 1; } } pk_log(PK_LOG_MANAGER_DEBUG, "Found %d new IPs", changes); /* 2nd pass: walk through list and remove obsolete entries * We only do this if we have null records which will let us re-discover * everything again if DNS went away temporarily. */ if (have_nulls) { obsolete = time(0) - (pkm->check_world_interval * 4); for (i = 0, fe = pkm->tunnels; i < pkm->tunnel_max; i++, fe++) { if ((fe->fe_hostname != NULL) && (fe->ai.ai_addr != NULL) && (fe->last_configured < obsolete) && (fe->last_ping < obsolete) && (fe->conn.sockfd <= 0)) { free(fe->fe_hostname); free_addrinfo_data(&fe->ai); fe->fe_hostname = NULL; } } } PK_CHECK_MEMORY_CANARIES; return changes; }
int main(int argc, char **argv) { struct pk_manager *m; unsigned int tmp_uint; char* proto; char* kitename; char* secret; int gotargs = 0; int verbosity = 0; int use_ipv4 = 1; int fes_v4 = 0; #ifdef HAVE_IPV6 int use_ipv6 = 1; int fes_v6 = 0; #endif int use_current = 1; int use_ssl = 1; int use_evil = 0; int use_watchdog = 0; int max_conns = 25; int spare_frontends = 0; char* fe_hostname = NULL; char* ddns_url = PAGEKITE_NET_DDNS; int ac; int pport; int lport; SSL_CTX* ssl_ctx; /* FIXME: Is this too lame? */ srand(time(0) ^ getpid()); pks_global_init(PK_LOG_NORMAL); while (-1 != (ac = getopt(argc, argv, "46c:B:CE:F:In:qRSvWZ"))) { switch (ac) { case '4': use_ipv4 = 0; break; case '6': #ifdef HAVE_IPV6 use_ipv6 = 0; #endif break; case 'C': use_current = 0; break; case 'v': verbosity++; break; case 'q': verbosity--; break; case 'I': use_ssl = 0; break; case 'R': pk_state.fake_ping = 1; break; case 'S': ddns_url = NULL; break; case 'W': use_watchdog = 1; break; case 'Z': use_evil = 1; break; case 'F': gotargs++; fe_hostname = strdup(optarg); break; case 'B': gotargs++; if (1 == sscanf(optarg, "%u", &pk_state.bail_on_errors)) break; usage(1); case 'c': gotargs++; if (1 == sscanf(optarg, "%d", &max_conns)) break; usage(1); case 'E': gotargs++; if (1 == sscanf(optarg, "%u", &tmp_uint)) { pk_state.conn_eviction_idle_s = tmp_uint; break; } usage(1); case 'n': gotargs++; if (1 == sscanf(optarg, "%d", &spare_frontends)) break; usage(1); default: usage(1); } gotargs++; } if ((argc-1-gotargs) < 5 || ((argc-1-gotargs) % 5) != 0) usage(1); signal(SIGUSR1, &raise_log_level); pk_state.log_mask = ((verbosity < 0) ? PK_LOG_ERRORS : ((verbosity < 1) ? PK_LOG_NORMAL : ((verbosity < 2) ? PK_LOG_DEBUG : PK_LOG_ALL))); if (use_ssl) { PKS_SSL_INIT(ssl_ctx); } else { ssl_ctx = NULL; } if (NULL == (m = pkm_manager_init(NULL, 0, NULL, 1 + (argc-1-gotargs)/5, /* Kites */ PAGEKITE_NET_FE_MAX, max_conns, ddns_url, ssl_ctx))) { pk_perror(argv[0]); exit(1); } m->want_spare_frontends = spare_frontends; if (use_evil) { m->housekeeping_interval_min = 5; m->housekeeping_interval_max = 20; m->check_world_interval = 30; } if (use_watchdog) m->enable_watchdog = 1; for (ac = gotargs; ac+5 < argc; ac += 5) { if ((1 != sscanf(argv[ac+1], "%d", &lport)) || (1 != sscanf(argv[ac+4], "%d", &pport))) { usage(2); } proto = argv[ac+2]; kitename = argv[ac+3]; secret = argv[ac+5]; if ((NULL == (pkm_add_kite(m, proto, kitename, 0, secret, "localhost", lport))) || (use_current && (0 > (pkm_add_frontend(m, kitename, pport, FE_STATUS_AUTO))))) { pk_perror(argv[0]); exit(3); } } if (ddns_url != NULL) { if (fe_hostname) { if (0 > (fes_v4 = pkm_add_frontend(m, fe_hostname, 443, FE_STATUS_AUTO))) { pk_perror(argv[0]); exit(4); } } else if (((use_ipv4) && (0 >= (fes_v4 = pkm_add_frontend(m, PAGEKITE_NET_V4FRONTENDS, FE_STATUS_AUTO)))) #ifdef HAVE_IPV6 || ((use_ipv6) && (0 >= (fes_v6 = pkm_add_frontend(m, PAGEKITE_NET_V6FRONTENDS, FE_STATUS_AUTO)))) #endif ) { pk_perror(argv[0]); exit(4); } } if (0 == (fes_v4 + fes_v6)) { pk_error = ERR_NO_FRONTENDS; pk_perror(argv[0]); exit(4); } if (0 > pkm_run_in_thread(m)) { pk_perror(argv[0]); exit(5); } pkm_wait_thread(m); return 0; }