Esempio n. 1
0
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);
}
Esempio n. 2
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
 */
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);	
}
Esempio n. 3
0
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();
		}
	}
}
Esempio n. 4
0
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);
      }
  }
}
Esempio n. 5
0
/* 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;
 }
Esempio n. 6
0
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--;
	}
}
Esempio n. 7
0
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 */
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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;
}
Esempio n. 10
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;
}
Esempio n. 11
0
/* 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;
 }