void die(struct Peer *p) { char b = DIE; int i; for (i = 0; i < 5; ++i) sendto(sock, &b, 1, 0, &p->addr, p->addr_len); remove_peer(p); }
/** * Timer function for peer management. * This is registered as a timer by peer_manager_init() and gets called every * #PEER_MANAGER_TIMER seconds. Then it looks on what changed and triggers events. * @param now - time of call * @param ptr - generic pointer for timers - not used */ void peer_timer(time_t now,void *ptr) { peer *p,*n; LOG(L_DBG,"DBG:peer_timer(): taking care of peers...\n"); lock_get(peer_list_lock); p = peer_list->head; while(p){ lock_get(p->lock); n = p->next; if (p->activity+config->tc<=now){ LOG(L_INFO,"DBG:peer_timer(): Peer %.*s \tState %d \n",p->fqdn.len,p->fqdn.s,p->state); switch (p->state){ /* initiating connection */ case Closed: if (p->is_dynamic && config->drop_unknown_peers){ remove_peer(p); free_peer(p,1); break; } touch_peer(p); sm_process(p,Start,0,1,0); break; /* timeouts */ case Wait_Conn_Ack: case Wait_I_CEA: case Closing: case Wait_Returns: touch_peer(p); sm_process(p,Timeout,0,1,0); break; /* inactivity detected */ case I_Open: case R_Open: if (p->waitingDWA){ p->waitingDWA = 0; if (p->state==I_Open) sm_process(p,I_Peer_Disc,0,1,p->I_sock); if (p->state==R_Open) sm_process(p,R_Peer_Disc,0,1,p->R_sock); } else { p->waitingDWA = 1; Snd_DWR(p); touch_peer(p); } break; /* ignored states */ /* unknown states */ default: LOG(L_ERR,"ERROR:peer_timer(): Peer %.*s inactive in state %d\n", p->fqdn.len,p->fqdn.s,p->state); } } lock_release(p->lock); p = n; } lock_release(peer_list_lock); log_peer_list(L_INFO); }
static void handle_fd_set(isrv_state_t *state, fd_set *fds, int (*h)(int, void **)) { enum { LONG_CNT = sizeof(fd_set) / sizeof(long) }; int fds_pos; int fd, peer; /* need to know value at _the beginning_ of this routine */ int fd_cnt = FD_COUNT; if (LONG_CNT * sizeof(long) != sizeof(fd_set)) BUG_sizeof_fd_set_is_strange(); fds_pos = 0; while (1) { /* Find next nonzero bit */ while (fds_pos < LONG_CNT) { if (((long*)fds)[fds_pos] == 0) { fds_pos++; continue; } /* Found non-zero word */ fd = fds_pos * sizeof(long)*8; /* word# -> bit# */ while (1) { if (FD_ISSET(fd, fds)) { FD_CLR(fd, fds); goto found_fd; } fd++; } } break; /* all words are zero */ found_fd: if (fd >= fd_cnt) { /* paranoia */ DPRINTF("handle_fd_set: fd > fd_cnt?? (%d > %d)", fd, fd_cnt); break; } DPRINTF("handle_fd_set: fd %d is active", fd); peer = FD2PEER[fd]; if (peer < 0) continue; /* peer is already gone */ if (peer == 0) { handle_accept(state, fd); continue; } DPRINTF("h(fd:%d)", fd); if (h(fd, &PARAM_TBL[peer])) { /* this peer is gone */ remove_peer(state, peer); } else if (TIMEOUT) { TIMEO_TBL[peer] = monotonic_sec(); } } }
void udp_readable_cb(EV_P_ ev_io *w, int revents) { char b; struct sockaddr src; socklen_t len; struct Peer *p; (void) loop; (void) w; (void) revents; len = sizeof(src); recvfrom(sock, &b, 1, 0, &src, &len); p = get_peer(&src, len); switch (b) { case CON: printf("client wants to connect\n"); if (!p) { p = new_peer(); memcpy(&p->addr, &src, len); p->state = ACKNOWLEDGING; acknowledge(p); } else if (p->state == DEAD) { acknowledge(p); p->state = ACKNOWLEDGING; } return; case ACK: if (p && (p->state == CONNECTING || p->state == ESTABLISHED)) { establish(p); p->state = ESTABLISHED; printf("established\n"); } return; case EST: if (p && p->state == ACKNOWLEDGING) { printf("established\n"); p->state = ESTABLISHED; return; } case DIE: if (p) { printf("peer disconected\n"); remove_peer(p); } } }
/* Client Mode */ void *connectToPeer(void *temp) { struct sockaddr_in remote_addr; int new_fd; char *buffer = malloc(MAXBUFFSIZE), *buf1 = malloc(MAXBUFFSIZE), *buf2 = malloc(MAXBUFFSIZE); struct peerList *peer = (struct peerList *)temp; if (!add_peer(peer) && (peer->net_fd)) return NULL; /* Create TCP Socket */ if ((new_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("could not create socket"); exit(1); } memset((char *)&remote_addr, 0, sizeof(remote_addr)); remote_addr.sin_family = AF_INET; remote_addr.sin_port = htons(peer->listenPort); inet_aton((char *)inet_ntoa(peer->listenIP), &remote_addr.sin_addr); sprintf(buf1, "%s %d", inet_ntoa(local_info->listenIP), local_info->listenPort); sprintf(buf2, "%s %d", inet_ntoa(peer->listenIP), peer->listenPort); if (debug) printf("COMPARING %s --- %s\n", buf1, buf2); if (!(strcmp(buf1, buf2))) return NULL; puts("Client Mode:"); printf("NEW PEER: Connecting to %s:%d\n", inet_ntoa(remote_addr.sin_addr), ntohs(remote_addr.sin_port)); /* Connect to server */ if ((connect(new_fd, (struct sockaddr *)&remote_addr, sizeof(remote_addr))) < 0) { printf("NEW PEER: Peer Removed %s:%d: Failed to connect\n", inet_ntoa(peer->listenIP), peer->listenPort); if (debug) printf("errno: %d\n", errno); remove_peer(peer); } else { /* Create single link state packet */ strcpy(buffer, peer->tapDevice); peer->net_fd = new_fd; printf("NEW PEER: Connected to server %s:%d - %d\n", inet_ntoa(peer->listenIP), peer->listenPort, peer->net_fd); // sprintf(buffer, "0xabcd 2048%s blah blah", send_peerList(peer)); // send(peer->net_fd, buffer, strlen(buffer), 0); send_singleLinkStatePacket(peer); lsPacket->neighbors = HASH_COUNT(peers); if (debug) print_linkStatePacket(); } if (debug) puts("Leaving connectToPeer"); return NULL; }
static void handle_timeout(isrv_state_t *state, int (*do_timeout)(void **)) { int n, peer; peer = PEER_COUNT-1; /* peer 0 is not checked */ while (peer > 0) { DPRINTF("peer %d: time diff %d", peer, (int)(CURTIME - TIMEO_TBL[peer])); if ((CURTIME - TIMEO_TBL[peer]) >= TIMEOUT) { DPRINTF("peer %d: do_timeout()", peer); n = do_timeout(&PARAM_TBL[peer]); if (n) remove_peer(state, peer); } peer--; } }
static void handle_accept(isrv_state_t *state, int fd) { int n, newfd; /* suppress gcc warning "cast from ptr to int of different size" */ fcntl(fd, F_SETFL, (int)(ptrdiff_t)(PARAM_TBL[0]) | O_NONBLOCK); newfd = accept(fd, NULL, 0); fcntl(fd, F_SETFL, (int)(ptrdiff_t)(PARAM_TBL[0])); if (newfd < 0) { if (errno == EAGAIN) return; /* Most probably someone gave us wrong fd type * (for example, non-socket). Don't want * to loop forever. */ bb_perror_msg_and_die("accept"); } DPRINTF("new_peer(%d)", newfd); n = state->new_peer(state, newfd); if (n) remove_peer(state, n); /* unsuccesful peer start */ }
int run_command(const std::string& cmd) { if (cmd == "add_peer") { return add_peer(); } if (cmd == "remove_peer") { return remove_peer(); } if (cmd == "change_peers") { return change_peers(); } if (cmd == "reset_peer") { return reset_peer(); } if (cmd == "snapshot") { return snapshot(); } if (cmd == "transfer_leader") { return transfer_leader(); } LOG(ERROR) << "Unknown command `" << cmd << '\''; return -1; }
int remove_peer() { CHECK_FLAG(conf); CHECK_FLAG(peer); CHECK_FLAG(group); Configuration conf; if (conf.parse_from(FLAGS_conf) != 0) { LOG(ERROR) << "Fail to parse --conf=`" << FLAGS_conf << '\''; return -1; } PeerId removing_peer; if (removing_peer.parse(FLAGS_peer) != 0) { LOG(ERROR) << "Fail to parse --peer=`" << FLAGS_peer<< '\''; return -1; } CliOptions opt; opt.timeout_ms = FLAGS_timeout_ms; opt.max_retry = FLAGS_max_retry; butil::Status st = remove_peer(FLAGS_group, conf, removing_peer, opt); if (!st.ok()) { LOG(ERROR) << "Fail to remove_peer : " << st; return -1; } return 0; }
/** * Timer function for peer management. * This is registered as a timer by peer_manager_init() and gets called every * #PEER_MANAGER_TIMER seconds. Then it looks on what changed and triggers events. * @param now - time of call * @param ptr - generic pointer for timers - not used */ int peer_timer(time_t now,void *ptr) { peer *p,*n; int i; LM_DBG("peer_timer(): taking care of peers...\n"); lock_get(peer_list_lock); p = peer_list->head; while(p){ lock_get(p->lock); n = p->next; if (p->disabled && (p->state != Closed || p->state != Closing)) { LM_DBG("Peer [%.*s] has been disabled - shutting down\n", p->fqdn.len, p->fqdn.s); if (p->state == I_Open) sm_process(p, Stop, 0, 1, p->I_sock); if (p->state == R_Open) sm_process(p, Stop, 0, 1, p->R_sock); lock_release(p->lock); p = n; continue; } if (p->activity+config->tc<=now){ LM_DBG("peer_timer(): Peer %.*s State %d \n",p->fqdn.len,p->fqdn.s,p->state); switch (p->state){ /* initiating connection */ case Closed: if (p->is_dynamic && config->drop_unknown_peers){ remove_peer(p); free_peer(p,1); break; } if (!p->disabled) { touch_peer(p); sm_process(p,Start,0,1,0); } break; /* timeouts */ case Wait_Conn_Ack: case Wait_I_CEA: case Closing: case Wait_Returns: case Wait_Conn_Ack_Elect: touch_peer(p); sm_process(p,Timeout,0,1,0); break; /* inactivity detected */ case I_Open: case R_Open: if (p->waitingDWA){ p->waitingDWA = 0; if (p->state==I_Open) sm_process(p,I_Peer_Disc,0,1,p->I_sock); if (p->state==R_Open) sm_process(p,R_Peer_Disc,0,1,p->R_sock); LM_WARN("Inactivity on peer [%.*s] and no DWA, Closing peer...\n", p->fqdn.len, p->fqdn.s); } else { p->waitingDWA = 1; Snd_DWR(p); touch_peer(p); if (debug_heavy) { LM_DBG("Inactivity on peer [%.*s], sending DWR... - if we don't get a reply, the peer will be closed\n", p->fqdn.len, p->fqdn.s); } } break; /* ignored states */ /* unknown states */ default: LM_ERR("peer_timer(): Peer %.*s inactive in state %d\n", p->fqdn.len,p->fqdn.s,p->state); } } lock_release(p->lock); p = n; } lock_release(peer_list_lock); log_peer_list(); i = config->tc/5; if (i<=0) i=1; return i; }
/* Read from socket and write to tap */ void *handle_listen(void *temp) { struct peerList *peer = (struct peerList *)temp; int size; uint16_t type; char buffer[MAXBUFFSIZE], buffer2[MAXBUFFSIZE]; /* Listen for client packets and parse accordingly */ printf("Client connected from %s:%d - %d.\n", inet_ntoa(peer->listenIP), peer->listenPort, peer->in_fd); while (1) { if (debug) printf("///Start while loop for %s\n", send_peerList(peer)); memset(buffer, 0, MAXBUFFSIZE); size = recv(peer->in_fd, buffer, sizeof(buffer), 0); if (debug) printf("\nSIZE from %s: %d\n", send_peerList(peer), size); if (size > 0) { strncpy(buffer2, buffer, 6); type = (uint16_t)strtol(buffer2, (char **)&buffer2, 0); if (debug) printf("TYPE from %s: %x\n", send_peerList(peer), type); switch (type) { case PACKET_DATA: strncpy(buffer, buffer+7, sizeof(buffer)); decode_dataPacket(buffer); // next_field = strtok(buffer, " \n"); // printf("HUH!?! : %s\n", next_field); // next_field = strtok(NULL, " \n"); // printf("HUH!?! : %s\n", next_field); break; case PACKET_LINKSTATE: strncpy(buffer, buffer+7, sizeof(buffer)); decode_linkStatePacket(buffer, peer->in_fd); break; case PACKET_LEAVE: strncpy(buffer, buffer+10, sizeof(buffer)); decode_leavePacket(buffer); break; case PACKET_QUIT: send_quitPacket(); break; default: if (debug) printf("Negative.\n"); break; } } else if (size < 0) { printf("recv error from %s - %d | ERR: %d\n", send_peerList(peer), peer->in_fd, errno); remove_peer(peer); print_peerList(); print_linkStateRecords(); return NULL; break; } else if (size == 0) { printf("PEER: Peer Removed %s:%d: Peer disconnected\n", inet_ntoa(peer->listenIP), peer->listenPort); remove_peer(peer); print_peerList(); print_linkStateRecords(); return NULL; } printf("///End while loop for %s\n", send_peerList(peer)); } if (debug) puts("Leaving handle_listen"); return NULL; }