END_TEST START_TEST(test_peer_requests) { /* printf("Called peer test\n"); */ message * msg; peer * localhost; localhost = peer_create("localhost", "localhost"); ck_assert_int_eq(peer_add_request(localhost, \ message_create_echo(MESSAGE_TYPE_REQUEST, "hey")), RET_OK); ck_assert_int_eq(peer_add_request(localhost, \ message_create_echo(MESSAGE_TYPE_REQUEST, "mess2")), RET_OK); ck_assert_int_eq(peer_add_request(localhost, \ message_create_echo(MESSAGE_TYPE_REQUEST, "message3")), RET_OK); ck_assert_int_eq(peer_pop_request(localhost, &msg), RET_OK); ck_assert(msg != NULL); ck_assert_str_eq(msg->data.echo, "hey"); ck_assert_int_eq(peer_pop_request(localhost, &msg), RET_OK); ck_assert(msg != NULL); ck_assert_str_eq(msg->data.echo, "mess2"); ck_assert_int_eq(peer_pop_request(localhost, &msg), RET_OK); ck_assert(msg != NULL); ck_assert_str_eq(msg->data.echo, "message3"); }
END_TEST START_TEST(test_peer_resolve) { peer * p = peer_create("local", "127.0.0.1:8080"); ck_assert_int_eq(peer_resolve(p), RET_OK); ck_assert(p->_addr != NULL); char host[255], port[6]; getnameinfo(p->_addr->ai_addr, p->_addr->ai_addrlen, host, 255, port, 6, NI_NUMERICHOST | NI_NUMERICSERV); ck_assert_str_eq("127.0.0.1", host); ck_assert_str_eq("8080", port); }
void run_discovery_service_test(discovery_test test) { jnx_guid guid; int i; for (i = 0; i < 16; i++) { guid.guid[i] = i; } peerstore *store = peerstore_init(peer_create(guid, "127.0.0.1", "UserName", 10), 0); discovery_service *svc = discovery_service_create(1234, AF_INET, baddr, store); #ifdef DEBUG printf("[DEBUG] service: %p\n", svc); #endif int retval = test(svc); if (retval == CLEANUP) { discovery_service_cleanup(&svc); } }
END_TEST START_TEST(test_peer_connect) { char host[100] = "127.0.0.1"; char port[6] = TEST_PORT; char hostport[107]; sprintf(hostport, "%s:%s", host, port); peer * p = peer_create("local", hostport); /* creating server for test */ int server_sock = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP); struct addrinfo * ainfo, hint; memset(&hint, 0, sizeof(struct addrinfo)); hint.ai_family = AF_UNSPEC; hint.ai_socktype = SOCK_STREAM; hint.ai_flags = AI_PASSIVE; /* for NULLed host */ hint.ai_protocol = IPPROTO_TCP; hint.ai_canonname = NULL; hint.ai_addr = NULL; hint.ai_next = NULL; ck_assert_int_eq(getaddrinfo(host, port, &hint, &ainfo), 0); ck_assert_int_eq(bind(server_sock, ainfo->ai_addr, ainfo->ai_addrlen), 0); ck_assert_int_eq(listen(server_sock, 10), 0); ck_assert_int_eq(peer_connect(p), 0); int client_sock = accept(server_sock, NULL, NULL); char * msg = "testmsg"; send(p->sock, msg, 8, MSG_DONTWAIT); char buf[25]; recv(client_sock, buf, 8, MSG_DONTWAIT); ck_assert_str_eq(buf, "testmsg"); close(p->sock); close(client_sock); close(server_sock); }
/* Accept bgp connection. */ static int bgp_accept(struct thread *thread) { int bgp_sock; int accept_sock; union sockunion su; struct bgp_listener *listener = THREAD_ARG(thread); struct peer *peer; struct peer *peer1; char buf[SU_ADDRSTRLEN]; struct bgp *bgp = NULL; sockunion_init(&su); /* Register accept thread. */ accept_sock = THREAD_FD(thread); if (accept_sock < 0) { flog_err_sys(EC_LIB_SOCKET, "accept_sock is nevative value %d", accept_sock); return -1; } listener->thread = NULL; thread_add_read(bm->master, bgp_accept, listener, accept_sock, &listener->thread); /* Accept client connection. */ bgp_sock = sockunion_accept(accept_sock, &su); if (bgp_sock < 0) { flog_err_sys(EC_LIB_SOCKET, "[Error] BGP socket accept failed (%s)", safe_strerror(errno)); return -1; } set_nonblocking(bgp_sock); /* Obtain BGP instance this connection is meant for. * - if it is a VRF netns sock, then BGP is in listener structure * - otherwise, the bgp instance need to be demultiplexed */ if (listener->bgp) bgp = listener->bgp; else if (bgp_get_instance_for_inc_conn(bgp_sock, &bgp)) { if (bgp_debug_neighbor_events(NULL)) zlog_debug( "[Event] Could not get instance for incoming conn from %s", inet_sutop(&su, buf)); close(bgp_sock); return -1; } /* Set socket send buffer size */ setsockopt_so_sendbuf(bgp_sock, BGP_SOCKET_SNDBUF_SIZE); /* Check remote IP address */ peer1 = peer_lookup(bgp, &su); if (!peer1) { peer1 = peer_lookup_dynamic_neighbor(bgp, &su); if (peer1) { /* Dynamic neighbor has been created, let it proceed */ peer1->fd = bgp_sock; bgp_fsm_change_status(peer1, Active); BGP_TIMER_OFF( peer1->t_start); /* created in peer_create() */ if (peer_active(peer1)) BGP_EVENT_ADD(peer1, TCP_connection_open); return 0; } } if (!peer1) { if (bgp_debug_neighbor_events(NULL)) { zlog_debug( "[Event] %s connection rejected - not configured" " and not valid for dynamic", inet_sutop(&su, buf)); } close(bgp_sock); return -1; } if (CHECK_FLAG(peer1->flags, PEER_FLAG_SHUTDOWN)) { if (bgp_debug_neighbor_events(peer1)) zlog_debug( "[Event] connection from %s rejected due to admin shutdown", inet_sutop(&su, buf)); close(bgp_sock); return -1; } /* * Do not accept incoming connections in Clearing state. This can result * in incorect state transitions - e.g., the connection goes back to * Established and then the Clearing_Completed event is generated. Also, * block incoming connection in Deleted state. */ if (peer1->status == Clearing || peer1->status == Deleted) { if (bgp_debug_neighbor_events(peer1)) zlog_debug( "[Event] Closing incoming conn for %s (%p) state %d", peer1->host, peer1, peer1->status); close(bgp_sock); return -1; } /* Check that at least one AF is activated for the peer. */ if (!peer_active(peer1)) { if (bgp_debug_neighbor_events(peer1)) zlog_debug( "%s - incoming conn rejected - no AF activated for peer", peer1->host); close(bgp_sock); return -1; } if (bgp_debug_neighbor_events(peer1)) zlog_debug("[Event] BGP connection from host %s fd %d", inet_sutop(&su, buf), bgp_sock); if (peer1->doppelganger) { /* We have an existing connection. Kill the existing one and run with this one. */ if (bgp_debug_neighbor_events(peer1)) zlog_debug( "[Event] New active connection from peer %s, Killing" " previous active connection", peer1->host); peer_delete(peer1->doppelganger); } if (bgp_set_socket_ttl(peer1, bgp_sock) < 0) if (bgp_debug_neighbor_events(peer1)) zlog_debug( "[Event] Unable to set min/max TTL on peer %s, Continuing", peer1->host); peer = peer_create(&su, peer1->conf_if, peer1->bgp, peer1->local_as, peer1->as, peer1->as_type, 0, 0, NULL); hash_release(peer->bgp->peerhash, peer); hash_get(peer->bgp->peerhash, peer, hash_alloc_intern); peer_xfer_config(peer, peer1); UNSET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE); peer->doppelganger = peer1; peer1->doppelganger = peer; peer->fd = bgp_sock; vrf_bind(peer->bgp->vrf_id, bgp_sock, bgp_get_bound_name(peer)); bgp_fsm_change_status(peer, Active); BGP_TIMER_OFF(peer->t_start); /* created in peer_create() */ SET_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER); /* Make dummy peer until read Open packet. */ if (peer1->status == Established && CHECK_FLAG(peer1->sflags, PEER_STATUS_NSF_MODE)) { /* If we have an existing established connection with graceful * restart * capability announced with one or more address families, then * drop * existing established connection and move state to connect. */ peer1->last_reset = PEER_DOWN_NSF_CLOSE_SESSION; SET_FLAG(peer1->sflags, PEER_STATUS_NSF_WAIT); bgp_event_update(peer1, TCP_connection_closed); } if (peer_active(peer)) { BGP_EVENT_ADD(peer, TCP_connection_open); } return 0; }
void protocol_recvpacket(const char *buffer, const int buffer_len, struct udpsrvsession_s *session) { uint16_t len; int i; void *p; const struct protocol_ip *ip = (struct protocol_ip *) buffer; struct peer_s *peer; if (buffer_len < 4) return; len = ntohs(ip->tot_len); #if DEBUG > 2 log_info("UDP: sizes %d = %d.\n", len, buffer_len); if (buffer_len > 27) { uint16_t *ping = (uint16_t*) &buffer[26]; log_debug("Ping%d id: %d\n", ip->version, ntohs(*ping)); } #endif if (ip->version == 4) //IPv4 packet { if (session->peer == NULL || (session->peer->stat & PEER_STAT_ID) == 0 || buffer_len < 20) return; if (router_checksrc((struct in_addr *) &ip->daddr, &tun_selfpeer) != 0) { log_debug("Not for me: %s\n", inet_ntoa(*(struct in_addr *) &ip->daddr)); return; } if (router_checksrc((struct in_addr *) &ip->saddr, session->peer) != 0) { log_debug("Not from there: %s\n", inet_ntoa(*(struct in_addr *) &ip->saddr)); return; } if (len > buffer_len) { log_error("UDP: Invalid size %d > %d.\n", len, buffer_len); return; } tundev_write(buffer, len); } //else if (ip->version == 6) //IPv6 Packet else if (ip->version == PROTOCOL1_V && ip->ihl == 1) //Internal packets v1 { if (((struct protocol_1_s *) ip)->pid == PROTOCOL1_IDA) { log_debug("ACK...\n"); if (session->peer != NULL && (session->peer->stat & PEER_STAT_IDK) == 0) { pthread_mutex_lock(&session->peer->modify_mutex); session->peer->stat |= PEER_STAT_IDK; pthread_mutex_unlock(&session->peer->modify_mutex); } if ((session->peer->stat & PEER_STAT_ID) != 0) log_info("New peer authenticated.\n"); } else if (((struct protocol_1_s *) ip)->pid == PROTOCOL1_ID) { log_debug("ID...\n"); if (session->peer == NULL) session->peer = peer_create(); pthread_mutex_lock(&session->peer->modify_mutex); peer = session->peer; peer->udpsrvsession = session; if ((peer->stat & PEER_STAT_ID) == 0) { if (protocol_processpeer(peer, &((struct protocol_1id_s *) buffer)->peer, buffer_len - sizeof(struct protocol_1id_s) + sizeof(struct protocol_peer_s)) < 0) { log_error("invalid ID\n"); //-TODO: Check pthread_mutex_unlock(&peer->modify_mutex); peer_destroy(peer); return; } log_debug("Validating id.\n"); /* Check for valid routes shared */ if (protocol_checknameconstraints(peer) < 0) { log_debug ("Peer trying to request for unallowed network...\n"); pthread_mutex_unlock(&peer->modify_mutex); peer_destroy(peer); return; } peer->stat |= PEER_STAT_ID; timeout_update(&peer->timeout); if ((session->peer->stat & PEER_STAT_IDK) != 0) log_info("New peer authenticated.\n"); pthread_mutex_unlock(&peer->modify_mutex); if (peer_add(peer, session) < 1) { peer_destroy(peer); return; } } //-TODO: JOIN packets protocol_sendpacket(session, PROTOCOL1_IDA); if ((peer->stat & PEER_STAT_IDK) == 0) protocol_sendpacket(session, PROTOCOL1_ID); } else if (((struct protocol_1_s *) ip)->pid == PROTOCOL1_KA) { if (len > buffer_len) return; log_debug("KA...\n"); if (session->peer != NULL && (session->peer->stat & PEER_STAT_ID) != 0) { timeout_update(&session->peer->timeout); p = (void *) buffer + sizeof(struct protocol_1ka_s); while (p <= (void *) &buffer[len - 1]) { peer = peer_create(); i = protocol_processpeer(peer, (struct protocol_peer_s *) p, (int) ((void *) &buffer[len - 1] - p)); if (i < 0) { peer_destroy(peer); return; } p += i; if (router_existpeer (peer->shared_networks, peer->shared_networks_len) == 0) peer_addnew(peer); else peer_destroy(peer); } } } else { log_error("Unknown paquet\n"); return; } } else { log_error("Unknown paquet\n"); return; } if (len + 4 <= buffer_len) protocol_recvpacket(buffer + len, buffer_len - len, session); }
END_TEST START_TEST(test_peer_to_string) { peer * p = peer_create("local", "127.0.0.1"); ck_assert_str_eq(peer_to_string(p), "Peer<local>(127.0.0.1, -1)"); }