int fqd_remove_peer(const char *host, int port, const char *user, const char *pass, fq_rk *exchange, const char *prog) { fqd_peer_connection *peer, speer; peer_binding_info *bi = NULL; int i; memset(&speer, 0, sizeof(speer)); speer.host = (char *)host; speer.port = port; speer.user = (char *)user; speer.pass = (char *)pass; pthread_mutex_lock(&lock); /* Get a peer */ for(peer = list_head.next; peer; peer = peer->next) { if(!peercmp(peer, &speer)) { for(i=0; i<peer->n_bindings; i++) { bi = peer->bindings[i]; if(bi->disabled == false && fq_rk_cmp(exchange, &bi->exchange) && !strcmp(prog, bi->prog)) { bi->disabled = true; break; } } break; } } if(bi && peer->n_bindings == 1) { /* Special case, we must remove this so no one else can see it */ fqd_peer_connection *prev = &list_head; for(prev = &list_head; prev->next; prev = prev->next) { if(!peercmp(prev->next, peer)) { prev->next = peer->next; peer->next = NULL; break; } } } if(bi) { /* We found something and it is our job to turn it down */ if(peer->n_bindings == 1) fqd_peer_stop(peer); else fqd_peer_online_unbind(peer, bi); } pthread_mutex_unlock(&lock); return bi ? 0 : -1; }
static peer_t *minpeer() { peer_t *result = NULL; for (int i = 0; i < g.npeers; i++) { if (g.peer_set[i].req && (!result || peercmp((g.peer_set + i), result))) result = g.peer_set + i; } return result; }
int fqd_add_peer(uint64_t gen, const char *host, int port, const char *user, const char *pass, fq_rk *exchange, const char *prog, bool perm) { bool added_peer = false, added_binding = false; fqd_peer_connection *peer, speer; peer_binding_info *bi = NULL; int i; memset(&speer, 0, sizeof(speer)); speer.host = (char *)host; speer.port = port; speer.user = (char *)user; speer.pass = (char *)pass; pthread_mutex_lock(&lock); /* Get a peer */ for(peer = list_head.next; peer; peer = peer->next) { if(!peercmp(peer, &speer)) break; } if(!peer) { peer = calloc(1, sizeof(*peer)); peer->host = strdup(speer.host); peer->port = speer.port; peer->user = strdup(speer.user); peer->pass = strdup(speer.pass); peer->next = list_head.next; list_head.next = peer; added_peer = true; } /* Get a binding */ for(i=0; i<peer->n_bindings; i++) { bi = peer->bindings[i]; if(!fq_rk_cmp(exchange, &bi->exchange) && !strcmp(prog, bi->prog)) break; } if(i == peer->n_bindings) { bi = calloc(1, sizeof(*bi)); memcpy(&bi->exchange, exchange, sizeof(*exchange)); bi->route_id = FQ_BIND_ILLEGAL; bi->prog = strdup(prog); peer->n_bindings++; peer->bindings = realloc(peer->bindings, peer->n_bindings * sizeof(bi)); peer->bindings[peer->n_bindings - 1] = bi; added_binding = true; } /* This will force a rebind */ if(perm != bi->perm) added_binding = true; bi->perm = perm; bi->gen = gen; if(added_peer) fqd_peer_start(peer); else if(added_binding) fqd_peer_online_bind(peer, bi); pthread_mutex_unlock(&lock); return added_binding ? 0 : -1; }