static void clear_stale_peers(void * x) { PeerServer ** sp = &peers; PeerServer * s; time_t timenow = time(NULL); int keep_timer = 0; assert(is_dispatch_thread()); while ((s = *sp) != NULL) { if (s->expiration_time <= timenow) { /* Delete stale entry */ *sp = s->next; notify_listeners(s, PS_EVENT_REMOVED); s->listed = 0; peer_server_free(s); } else { keep_timer = 1; sp = &s->next; } } if (keep_timer) { post_event_with_delay(clear_stale_peers, NULL, PEER_DATA_REFRESH_PERIOD * 1000000); } else { stale_timer_active = 0; } }
int ini_server(const char * url, Protocol * p, TCFBroadcastGroup * b) { ChannelServer * serv = NULL; PeerServer * ps = NULL; Trap trap; if (!set_trap(&trap)) { bcg = NULL; proto = NULL; if (ps != NULL) peer_server_free(ps); errno = trap.error; return -1; } bcg = b; proto = p; ps = channel_peer_from_url(url); if (ps == NULL) str_exception(ERR_OTHER, "Invalid server URL"); peer_server_addprop(ps, loc_strdup("Name"), loc_strdup(PROXY_NAME)); peer_server_addprop(ps, loc_strdup("Proxy"), loc_strdup("")); SERVER_ADDPROP_HOOK; serv = channel_server(ps); if (serv == NULL) exception(errno); serv->new_conn = channel_new_connection; clear_trap(&trap); add_channel_redirection_listener(channel_redirection_listener); return 0; }
static void server_close(ChannelServer * serv) { ServerNP * s = server2np(serv); assert(is_dispatch_thread()); if (s->sock < 0) return; list_remove(&s->serv.servlink); if (list_is_empty(&channel_root) && list_is_empty(&channel_server_root)) shutdown_set_stopped(&channel_shutdown); list_remove(&s->servlink); peer_server_free(s->serv.ps); nopoll_conn_close(s->np_sock); nopoll_ctx_unref(s->np_ctx); s->sock = -1; }
PeerServer * peer_server_add(PeerServer * n, unsigned int stale_delta) { PeerServer ** sp = &peers; PeerServer * s; int type = PS_EVENT_ADDED; assert(!n->listed); assert(is_dispatch_thread()); while ((s = *sp) != NULL) { if (strcmp(s->id, n->id) == 0) { if (((s->flags & PS_FLAG_LOCAL) && !(n->flags & PS_FLAG_LOCAL)) || is_same(s, n)) { /* Never replace local entries with discovered ones */ s->expiration_time = time(NULL) + stale_delta; if (!(s->flags & PS_FLAG_LOCAL)) s->flags = n->flags; peer_server_free(n); notify_listeners(s, PS_EVENT_HEART_BEAT); return s; } *sp = s->next; s->listed = 0; peer_server_free(s); type = PS_EVENT_CHANGED; break; } sp = &s->next; } n->listed = 1; n->creation_time = time(NULL); n->expiration_time = n->creation_time + stale_delta; n->next = peers; peers = n; notify_listeners(n, type); if (!stale_timer_active) { stale_timer_active = 1; post_event_with_delay(clear_stale_peers, NULL, PEER_DATA_REFRESH_PERIOD * 1000000); } return n; }
static int lua_peer_gc(lua_State *L) { struct peer_extra *pse = NULL; assert(L == luastate); if(lua_gettop(L) != 1 || (pse = lua2peer(L, 1)) == NULL) { luaL_error(L, "wrong number or type of arguments"); } if(pse->managed == 0) { trace(LOG_LUA, "lua_peer_gc %p", pse->ps); peer_server_free(pse->ps); pse->ps = NULL; } return 0; }
void peer_server_remove(const char *id) { PeerServer ** sp = &peers; PeerServer * s; assert(is_dispatch_thread()); while ((s = *sp) != NULL) { if (strcmp(s->id, id) == 0) { *sp = s->next; notify_listeners(s, PS_EVENT_REMOVED); s->listed = 0; peer_server_free(s); break; } sp = &s->next; } }
static void connect_done(void * args, int error, Channel * c2) { ConnectInfo * info = (ConnectInfo *)args; Channel * c1 = info->c1; if (!is_channel_closed(c1)) { assert(c1->state == ChannelStateRedirectReceived); if (error) { fprintf(stderr, "cannot connect to peer: %s\n", dest_url); channel_close(c1); } else { proxy_create(c1, c2); } } else if (!error) { channel_close(c2); } channel_unlock(c1); peer_server_free(info->ps); loc_free(info); }