Exemple #1
0
void WSService::on_tcp_post_init(WSClass& c, websocketpp::connection_hdl hdl) {
	log_->trace() << log_tag() << BOOST_CURRENT_FUNCTION;

	auto connection_ptr = c.get_con_from_hdl(hdl);
	if(!c.is_server())
		connection_ptr->add_subprotocol(subprotocol_);

	try {
		// Validate SSL certificate
		X509* x509 = SSL_get_peer_certificate(connection_ptr->get_socket().native_handle());
		if(!x509) throw connection_error("Certificate error");

		// Detect loopback
		connection& conn = ws_assignment_[hdl];
		conn.remote_pubkey = pubkey_from_cert(x509);
		conn.remote_endpoint = connection_ptr->get_raw_socket().remote_endpoint();

		X509_free(x509);

		if(provider_.is_loopback(conn.remote_pubkey) || provider_.is_loopback(conn.remote_endpoint)) {
			provider_.mark_loopback(conn.remote_endpoint);
			throw connection_error("Loopback detected");
		}
	}catch(std::exception& e) {
		log_->warn() << log_tag() << BOOST_CURRENT_FUNCTION << " e:" << e.what();
		connection_ptr->terminate(websocketpp::lib::error_code());
	}
}
void lcb_server_connect_handler(lcb_connection_t conn, lcb_error_t err)
{
    lcb_server_t *server = (lcb_server_t *)conn->data;
    struct nameinfo_common nistrs;
    int sasl_in_progress;
    int should_do_sasl = 0;

    if (err != LCB_SUCCESS) {
        connection_error(server, err);
        return;
    }


    server->inside_handler = 1;

    sasl_in_progress = (server->sasl_conn != NULL);
    if (!get_nameinfo(conn, &nistrs)) {
        /** This normally shouldn't happen! */
        connection_error(server, LCB_NETWORK_ERROR);
    }

    if (!sasl_in_progress) {
        int sasl_ok = cbsasl_client_new("couchbase", conn->host,
                                         nistrs.local, nistrs.remote,
                                         server->instance->sasl.callbacks, 0,
                                         &server->sasl_conn);
        lcb_assert(sasl_ok == SASL_OK);
    }

    if (server->index == -1) {
        should_do_sasl = 1;
    } else if (vbucket_config_get_user(server->instance->config.handle) != NULL) {
        should_do_sasl = 1;
    }

    if (should_do_sasl) {
        if (!sasl_in_progress) {
            start_sasl_auth_server(server);
        }
    } else {
        /* No SASL AUTH needed */
        lcb_server_connected(server);
    }

    lcb_connection_cancel_timer(conn);
    lcb_sockrw_apply_want(conn);
    server->inside_handler = 0;
}
static void connection_readable_cb(EV_P_ struct ev_io *watcher, int revents)
{
  connection_t *c = get_ev_data(connection, watcher, read);
  char          buf[BUFFER_CHUNK_SIZE];
  
  if (EV_ERROR & revents) {
    connection_error(c, "Error reading on connection socket");
    return;
  }
  
  size_t received = recv(c->fd, buf, BUFFER_CHUNK_SIZE, 0);
  ev_timer_again(c->loop, &c->timeout_watcher);
  
  if (received == -1) {
    /* error, closing connection */
    connection_errno(c);
    return;
  }
  
  if (received == 0) {
    /* received 0 byte, read again next loop */
    return;
  }
  
  trace(c->backend, buf, received);
  
  request_parse(c, buf, received);
}
 client::client(const string_type & host, unsigned int port)
 {
   char err[ANET_ERR_LEN];
   socket_ = anetTcpConnect(err, const_cast<char*>(host.c_str()), port);
   if (socket_ == ANET_ERR) 
     throw connection_error(err);
   anetTcpNoDelay(NULL, socket_);
 }
Exemple #5
0
/**
 * @brief UDPClient::udpListnerStart
 * @param ip    监听IP地址
 * @param port  监听端口号
 */
void UDPClient::udpListnerStart(const QHostAddress ip, const int port)
{
    qDebug("%s", __func__);
    udpListnerSocket = new QUdpSocket(this);
    if(!udpListnerSocket->bind(ip, port)) {
        qWarning("NULL");
    }
    connect(udpListnerSocket, SIGNAL(readyRead()), this, SLOT(readyListnerRead()));
    connect(udpListnerSocket, SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(connection_error(QAbstractSocket::SocketError)));
}
Exemple #6
0
    void
    check_connection(void) const
    {
      switch (xcb_connection_has_error(m_c.get())) {
        case XCB_CONN_ERROR:
          throw(connection_error(
                XCB_CONN_ERROR, "XCB_CONN_ERROR"));

        case XCB_CONN_CLOSED_EXT_NOTSUPPORTED:
          throw(connection_error(XCB_CONN_CLOSED_EXT_NOTSUPPORTED,
                                 "XCB_CONN_CLOSED_EXT_NOTSUPPORTED"));

        case XCB_CONN_CLOSED_MEM_INSUFFICIENT:
          throw(connection_error(XCB_CONN_CLOSED_MEM_INSUFFICIENT,
                                 "XCB_CONN_CLOSED_MEM_INSUFFICIENT"));

        case XCB_CONN_CLOSED_REQ_LEN_EXCEED:
          throw(connection_error(XCB_CONN_CLOSED_REQ_LEN_EXCEED,
                                 "XCB_CONN_CLOSED_REQ_LEN_EXCEED"));

        case XCB_CONN_CLOSED_PARSE_ERR:
          throw(connection_error(XCB_CONN_CLOSED_PARSE_ERR,
                                 "XCB_CONN_CLOSED_PARSE_ERR"));

        case XCB_CONN_CLOSED_INVALID_SCREEN:
          throw(connection_error(XCB_CONN_CLOSED_INVALID_SCREEN,
                                 "XCB_CONN_CLOSED_INVALID_SCREEN"));
      };
    }
Exemple #7
0
/**
 * @brief UDPClient::udpStart
 * @param localIp
 * @param listnerPort
 * @param remoteIp
 * @param remotePort
 * 启动UDP服务
 */
void UDPClient::udpStart(const QHostAddress localIp, const int listnerPort, const QHostAddress remoteIp, const int remotePort)
{
    qDebug("%s", __func__);
    // 开启发送
    if(udpSendSocket == nullptr) {
        udpSendSocket = new QUdpSocket(this);
        connect(udpSendSocket, SIGNAL(readyRead()), this, SLOT(readySendRead()));
        connect(udpSendSocket, SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(connection_error(QAbstractSocket::SocketError)));
    }

    // 开启接收Socket
    udpListnerStart(localIp, listnerPort);
}
Exemple #8
0
void
tws::scidb::pool_connection::close()
{
  if(handle_)
  {
    const ::scidb::SciDB& db_api = ::scidb::getSciDB();
    
    try
    {
      db_api.disconnect(handle_);
    }
    catch(const ::scidb::Exception& e)
    {
      throw connection_error() << tws::error_description(std::string(e.what()));
    }
    catch(...)
    {
      throw connection_error() << tws::error_description("could not close connection with coordinator server.");
    }
    
    handle_ = nullptr;
  }
}
Exemple #9
0
void
tws::scidb::pool_connection::open()
{
  close();
  
  const ::scidb::SciDB& db_api = ::scidb::getSciDB();
  
  try
  {
    handle_ = db_api.connect(coordinator_address_, coordinator_port_);

    if(handle_ == nullptr)
      throw connection_error() << tws::error_description("could not connect to the coordinator server.");
  }
  catch(const ::scidb::Exception& e)
  {
    throw connection_error() << tws::error_description(std::string(e.what()));
  }
  catch(...)
  {
    throw connection_error() << tws::error_description("could not connect to the coordinator server.");
  }
}
Exemple #10
0
unique_ptr<SocketConnection> Connect(const string& host, int port) {
  static bool initialized = InitializeSockets();
  if (!initialized) {
    throw socket_error("Unable to initialize sockets.");
  }

  struct addrinfo hints;
  memset(&hints, 0, sizeof(addrinfo));
  hints.ai_family = PF_UNSPEC;
  hints.ai_socktype =  SOCK_STREAM;
  hints.ai_protocol = IPPROTO_IP;
  
  const string port_string = std::to_string(port);
  struct addrinfo* address = nullptr;
  int result = getaddrinfo(host.c_str(), port_string.c_str(), &hints, &address);
  for (struct addrinfo* res = address; res != nullptr; res = res->ai_next) {
    SOCKET s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    if (s == INVALID_SOCKET) {
      continue;
    }
    int result = connect(s, res->ai_addr, static_cast<int>(res->ai_addrlen));
    if (result == SOCKET_ERROR) {
      closesocket(s);
      s = INVALID_SOCKET;
      continue;
    } else {
      // success;
      freeaddrinfo(address);
      if (!SetNonBlockingMode(s)) {
        LOG << "Unable to put socket into nonblocking mode.";
        closesocket(s);
        s = INVALID_SOCKET;
        continue;
      }
      if (!SetNoDelayMode(s)) {
        LOG << "Unable to put socket into nodelay mode.";
        closesocket(s);
        s = INVALID_SOCKET;
        continue;
      }
      return unique_ptr<SocketConnection>(new SocketConnection(s, host, port));
    }
  }
  throw connection_error(host, port);
}
Exemple #11
0
void TIDorb::core::comm::UDPConnection::read(unsigned char* buffer, size_t buffer_size,
                                             size_t offset, size_t length)
{
  try {
    while (length > 0) {

      // Copy datagram bytes available in read buffer
      size_t available = datagram_size - datagram_offset;
      if (available) {
        size_t to_copy = MIN(length, available);
        memcpy(buffer + offset, datagram_buffer + datagram_offset, to_copy);

        offset += to_copy;
        length -= to_copy;

        datagram_offset += to_copy;

      } else {

        // Read another datagram
        TIDSocket::DatagramPacket datagram(datagram_buffer, datagram_max_size,
                                           0, datagram_max_size);
        socket->receive(datagram);

        datagram_size   = datagram.getLength();
        if (datagram_size < 0) {
          throw CORBA::COMM_FAILURE("read error", 0, CORBA::COMPLETED_NO);
        }
      
        datagram_offset = 0;

      }
    }

  } catch(const TIDSocket::Exception& e) {
    CORBA::COMM_FAILURE connection_error(e.what(), 0, CORBA::COMPLETED_NO);
    // TODO: ?seguro que este close()?
    close_by_broken_connection(connection_error);
    throw connection_error;
  }

}
Exemple #12
0
	void Client::connect( const char* ipcpath )
	{

		if( !connected_ ) {
			if( !conn_ ) {
				conn_ = xmmsc_init( name_.c_str() );
			}
			if( !xmmsc_connect( conn_, ipcpath ) ) {

				throw connection_error( xmmsc_get_last_error( conn_ ) );

			}
			connected_ = true;
		}

		if( mainloop_ && !listener_ && typeid(mainloop_) == typeid(MainLoop) ) {
			listener_ = new Listener( conn_ );
			dynamic_cast<MainLoop*>(mainloop_)->addListener( listener_ );
		}

	}
static void connection_writable_cb(EV_P_ struct ev_io *watcher, int revents)
{
  connection_t *c = get_ev_data(connection, watcher, write);  
  
  if (EV_ERROR & revents) {
    connection_error(c, "Error writing on connection socket");
    return;
  }
  
  if (c->write_buffer.len == 0)
    return;
  
  char   *buf  = (char *) c->write_buffer.ptr + c->write_buffer.offset;
  size_t  len  = c->write_buffer.len - c->write_buffer.offset;
  
  trace(c->backend, buf, len);
  
  size_t  sent = send(c->fd, buf, len, 0);
  ev_timer_again(c->loop, &c->timeout_watcher);
  
  if (sent < 0) {
    /* error, closing connection */
    connection_errno(c);
    return;
  }
  
  c->write_buffer.offset += sent;
  
  if (buffer_eof(&c->write_buffer)) {
    /* if all the buffer is written we can clear it from memory */
    buffer_reset(&c->write_buffer);
    
    /* we can stream the request, so do not close it unless it's marked
     * as finished */
    if (c->finished)
      connection_close(c);
  }
}
Exemple #14
0
void TIDorb::core::comm::UDPConnection::write(unsigned char* buffer, 
                                              size_t buffer_size, 
                                              size_t offset, size_t length)
{
  try {
    size_t numWrittenNow = 0;
    
    TIDSocket::InetSocketAddress addr(initial_point._host, initial_point._port,
                                      _orb->conf().prefer_ipv6);
    TIDSocket::DatagramPacket datagram(buffer, buffer_size, offset, length, addr);
    char* interface = NULL;
    if (_orb->conf().prefer_ipv6) {
      string point = initial_point._host;
      string::size_type colon_position = point.find('%');
      if (colon_position != string::npos)
        interface = CORBA::string_dup(point.substr(colon_position + 1).c_str());
    }
    while (length > 0) {
      
      socket->send(datagram);

      numWrittenNow = datagram.getLength();      
      if (numWrittenNow < 0) {
        throw CORBA::COMM_FAILURE("write error", 0, CORBA::COMPLETED_NO);
      }

      offset += numWrittenNow;
      length -= numWrittenNow;

      datagram.setData(buffer, buffer_size, offset, length); 
    }

  } catch(const TIDSocket::Exception& e) {
    CORBA::COMM_FAILURE connection_error(e.what(), 0, CORBA::COMPLETED_NO);
    close_by_broken_connection(connection_error);
    throw connection_error;
  }
}
Exemple #15
0
 void cluster::try_connect_next_endpoint(connect_handler handler,
                                         boost::asio::io_service &ioService)
 {
     check_for_expired_deaths();
     
     //any more endpoints left?
     if (_liveEndpoints.size() == 0)
     {
         handler(nullptr, connection_error("no nodes available"));
         return;
     }
     
     cluster_endpoint::ptr ep = this->random_endpoint();
     cluster_connection::ptr conn = std::make_shared<cluster_connection>(ep, ioService);
     
     connect_context ctx =
         {
             handler,
             ep,
             conn
         };
     
     conn->connect(std::bind(&cluster::connection_result, this, _1, ctx));
 }
Exemple #16
0
int server(unsigned short port, int demarcaciones, int taxPorDemarcacion, int iters, int timeout_millis, int txdelay_millis, bool debug) {
	connection_t conn;
	packet_t outgoing;
	packet_t * incoming;

	if (!connection_server(&conn, port)) {
		fprintf(stderr, "Unable to spawn server on port %u: ", port);
		connection_error(&conn, stderr);
		fprintf(stderr, "\n");
		return 1;
	}

	if (debug) {
		connection_debug(&conn, stderr);
	}

	gestion_taxi_t * taxis = calloc(demarcaciones * taxPorDemarcacion, sizeof(gestion_taxi_t));
	if (taxis == NULL) {
		fprintf(stderr, "Failed to allocate memory for taxi stats structure: %s\n", strerror(errno));
		return 1;
	}

	fprintf(stderr, "Waiting for clientes at port: [%d]\n", port);
	int connected = 0;
	int pendingAccAck = demarcaciones * taxPorDemarcacion;
	while (pendingAccAck > 0) {
		if (!connection_receive(&conn, &incoming, NULL)) { /* TODO: check how to safely implement a timeout here */
			fprintf(stderr, "Error receiving login packet: ");
			connection_error(&conn, stderr);
			fprintf(stderr, "\n");

			if (connection_dead(&conn)) {
				connection_close(&conn);
				free(taxis);
				return 1;
			}

			continue;
		}

		bool duplicate = false;
		int pos;
		switch (incoming->type) {
			case PACKET_TYPE_LOGIN:
				if (incoming->login.version != PACKET_VERSION) {
					fprintf(stderr, "Got LOGIN with version %08X but server version is %08X\n", incoming->login.version, PACKET_VERSION);
					connection_discard(&conn);
					continue;
				}
				connection_accept(&conn);

				for (pos = 0; pos < connected; pos++) {
					if (connection_cmp(&taxis[pos].conexionConTaxi, &conn)) {
						duplicate = true;
						fprintf(stderr, "Got duplicated login packet from taxi %d-%d. Re-sending acknowledgement\n", pos / taxPorDemarcacion, pos % taxPorDemarcacion);
						break;
					}
				}

				if (!duplicate) {
					if (connected == taxPorDemarcacion * demarcaciones) {
						fprintf(stderr, "Received new LOGIN but all taxis have been already registered\n");
						continue;
					}

					fprintf(stderr, "Registered new taxi %d-%d\n", connected / taxPorDemarcacion, connected % taxPorDemarcacion);
					memcpy(&taxis[connected].conexionConTaxi, &conn, sizeof(conn));
					connected++;
				}

				outgoing.type = PACKET_TYPE_ACCEPT;
				outgoing.accept.zone = pos / taxPorDemarcacion;
				outgoing.accept.id = pos % taxPorDemarcacion;
				outgoing.accept.neighbors = taxPorDemarcacion - 1;
				outgoing.accept.ticks = iters;
				outgoing.accept.timeout = timeout_millis;
				outgoing.accept.txdelay = txdelay_millis;
				if (!connection_send(&conn, &outgoing)) {
					fprintf(stderr, "Error replying to login packet: ");
					connection_error(&conn, stderr);
					fprintf(stderr, "\n");
					connection_close(&conn);
					free(taxis);
					return 1;
				}

				break;

			case PACKET_TYPE_ACCACK:
				if (incoming->accack.zone >= demarcaciones || incoming->accack.id >= taxPorDemarcacion) {
					fprintf(stderr, "Received illegal accept acknowledgement from taxi %u-%u\n", incoming->accack.zone, incoming->accack.id);
					connection_discard(&conn);
					continue;
				}
				connection_accept(&conn);

				gestion_taxi_t * taxi = &taxis[incoming->accack.zone * taxPorDemarcacion + incoming->accack.id];
				if (!taxi->hasAckdAccept) {
					taxi->hasAckdAccept = true;
					pendingAccAck--;
				}
				break;

			default:
				connection_discard(&conn);
				fprintf(stderr, "Unexpected packet %s during login phase. Discarding.\n", packet_name(incoming));
				continue;
		}
	}

	outgoing.type = PACKET_TYPE_START;
	for (int pos = 0; pos < demarcaciones * taxPorDemarcacion; pos++) {
		if (!connection_send(&taxis[pos].conexionConTaxi, &outgoing)) {
			fprintf(stderr, "Error sending start packet: ");
			connection_error(&conn, stderr);
			fprintf(stderr, "\n");
			connection_close(&conn);
			free(taxis);
			return 1;
		}
	}

	int statsRcv = 0;
	struct timeval defaulttimeout = { (timeout_millis * 2) / 1000, ((timeout_millis * 2) % 1000) * 1000 };
	struct timeval timeout = defaulttimeout;
	while (statsRcv < demarcaciones * taxPorDemarcacion) {
		if (!connection_receive(&conn, &incoming, NULL)) {
			fprintf(stderr, "Error receiving packet in main loop: ");
			connection_error(&conn, stderr);
			fprintf(stderr, "\n");

			if (conn.err == CONNERR_TIMEOUT) {
				break;
			}

			if (connection_dead(&conn)) {
				connection_close(&conn);
				free(taxis);
				return 1;
			}

			continue;
		}

		gestion_taxi_t * taxi;
		switch (incoming->type) {
			case PACKET_TYPE_ACCACK:
				outgoing.type = PACKET_TYPE_START;
				if (!connection_send(&conn, &outgoing)) {
					fprintf(stderr, "Failed to send start packet in main loop: ");
					connection_error(&conn, stderr);
					fprintf(stderr, "\n");
					connection_close(&conn);
					return 1;
				}
				timeout = defaulttimeout;
				break;

			case PACKET_TYPE_POSITION:
				if (incoming->position.zone > demarcaciones || incoming->position.id > taxPorDemarcacion) {
					fprintf(stderr, "Received position from illegal taxi %u-%u\n", outgoing.position.zone, outgoing.position.id);
					connection_discard(&conn);
					continue;
				}

				for (int neighbor = 0; neighbor < taxPorDemarcacion; neighbor++) {
					if (neighbor == incoming->position.id) {
						continue;
					}

					if (!connection_send(&taxis[incoming->position.zone * taxPorDemarcacion + neighbor].conexionConTaxi, incoming)) {
						fprintf(stderr, "Error forwarding position packet: ");
						connection_error(&taxis[incoming->position.zone * taxPorDemarcacion + neighbor].conexionConTaxi, stderr);
						fprintf(stderr, "\n");
						connection_close(&conn);
						free(taxis);
						return 1;
					}
				}
				timeout = defaulttimeout;
				connection_accept(&conn);
				break;

			case PACKET_TYPE_POSACK:
				if (incoming->posack.zone > demarcaciones || incoming->posack.id > taxPorDemarcacion) {
					fprintf(stderr, "Received acknowledgement from illegal taxi %u-%u\n", incoming->posack.zone, incoming->posack.id);
					break;
				}

				if (incoming->posack.neighbor > taxPorDemarcacion) {
					fprintf(stderr, "Received acknowledgement from %u-%u targeting out-of-bounds taxi %u-%u\n", incoming->posack.zone, incoming->posack.id, incoming->posack.zone, incoming->posack.neighbor);
					break;
				}

				taxi = &taxis[incoming->posack.zone * taxPorDemarcacion + incoming->posack.neighbor];
				if (!connection_send(&taxi->conexionConTaxi, incoming)) {
					fprintf(stderr, "Error forwarding acknowledgement packet: ");
					connection_error(&taxi->conexionConTaxi, stderr);
					fprintf(stderr, "\n");
					connection_close(&conn);
					free(taxis);
					return 1;
				}
				timeout = defaulttimeout;
				connection_accept(&conn);
				break;

			case PACKET_TYPE_STATS:
				taxi = &taxis[incoming->stats.zone * taxPorDemarcacion + incoming->stats.id];
				if (!taxi->hasSentStats) {
					printf("%u, %u, %u, %u, %u, %u, %u, %u\n",
						incoming->stats.zone,
						incoming->stats.id,
						incoming->stats.ticks,
						incoming->stats.posrcv,
						incoming->stats.ackrcv,
						incoming->stats.itmin,
						incoming->stats.itavg,
						incoming->stats.itmax
					);
					taxi->hasSentStats = true;
					statsRcv++;
				}

				outgoing.type = PACKET_TYPE_STATACK;
				if (!connection_send(&taxi->conexionConTaxi, &outgoing)) {
					fprintf(stderr, "Error sending stats acknowledgement packet: ");
					connection_error(&taxi->conexionConTaxi, stderr);
					fprintf(stderr, "\n");
					connection_close(&conn);
					free(taxis);
					return 1;
				}

				timeout = defaulttimeout;
				connection_accept(&conn);
				break;

			default:
				fprintf(stderr, "Unexpected packet %s during main loop\n", packet_name(incoming));
				connection_discard(&conn);
				continue;
		}
	}

	// TODO: Interpretar estadísticas
	return 0;
}
Exemple #17
0
int main(int argc, char *argv[])
{
	/* check arguments, need hostname/IP and port of cache-server */
	if (argc < 3) {
		printf("Usage: %s [host] [port]\n", argv[0]);
		return EXIT_FAILURE;
	}

	struct tr_socket tr_tcp;
	struct tr_tcp_config tcp_config = { argv[1], argv[2], NULL };
	struct rtr_socket rtr_tcp;
	struct rtr_mgr_config *conf;
	struct rtr_mgr_group groups[1];

	/* init a TCP transport and create rtr socket */
	tr_tcp_init(&tcp_config, &tr_tcp);
	rtr_tcp.tr_socket = &tr_tcp;

	/* create a rtr_mgr_group array with 1 element */
	groups[0].sockets = malloc(1 * sizeof(struct rtr_socket *));
	groups[0].sockets_len = 1;
	groups[0].sockets[0] = &rtr_tcp;
	groups[0].preference = 1;

	if (rtr_mgr_init(&conf, groups, 1, 30, 600, 600, NULL, NULL,
			 &connection_status_callback, NULL) < 0)
		return EXIT_FAILURE;

	rtr_mgr_start(conf);

	char input[256];
	int sleep_counter = 0;

	/* wait till at least one rtr_mgr_group is synchronized with server */
	while (!rtr_mgr_conf_in_sync(conf)) {
		if (connection_error(connection_status))
			return EXIT_FAILURE;

		sleep(1);
		sleep_counter++;
		if (sleep_counter >= connection_timeout) {
			/*
			 * Wait for input before printing "timeout",
			 * to avoid "broken pipee error while communicating
			 * with the Python program
			 */
			if (fgets(input, 256, stdin))
				;
			printf("timeout\n");
			fflush(stdout);
			return EXIT_FAILURE;
		}
	}

	char ip[128];
	int mask;
	int asn;
	int counter;
	/* loop for input */
	while (1) {
		int input_len;
		int spaces;

		/* recheck connection, exit on failure */
		if (connection_error(connection_status))
			return EXIT_FAILURE;

		/* try reading from stdin, exit on failure */
		if (!fgets(input, 256, stdin)) {
			printf("input error\n");
			return EXIT_FAILURE;
		}

		/* remove newline, if present */
		input_len = strlen(input) - 1;
		if (input[input_len] == '\n')
			input[input_len] = '\0';

		/* check if there are exactly 3 arguments */
		spaces = 0;
		for (counter = 0; counter < input_len; counter++) {
			if (input[counter] == ' ' &&
			    input[counter + 1] != ' ' &&
			    input[counter + 1] != '\0' && counter != 0)
				spaces++;
		}

		/* check input matching pattern */
		if (spaces != 2) {
			printf("Arguments required: IP Mask ASN\n");
			fflush(stdout);
			continue;
		}

		char delims[] = " ";
		char *input_tok = NULL;

		input_tok = strtok(input, delims);
		strcpy(ip, input_tok);
		input_tok = strtok(NULL, delims);
		mask = atoi(input_tok);
		input_tok = strtok(NULL, delims); asn = atoi(input_tok);

		struct lrtr_ip_addr pref;
		enum pfxv_state result;
		struct pfx_record *reason = NULL;
		unsigned int reason_len = 0;

		lrtr_ip_str_to_addr(ip, &pref);
		/* do validation */
		pfx_table_validate_r(groups[0].sockets[0]->pfx_table, &reason,
				     &reason_len, asn, &pref, mask, &result);

		int validity_code = -1;
		/* translate validation result */
		if (result == BGP_PFXV_STATE_VALID)
			validity_code = 0;
		else if (result == BGP_PFXV_STATE_NOT_FOUND)
			validity_code = 1;
		else if (result == BGP_PFXV_STATE_INVALID)
			validity_code = 2;

		/* IP Mask BGP-ASN| */
		printf("%s %d %d|", ip, mask, asn);

		/* ROA-ASN IP MaskMin MaskMax, ... */
		if (reason && (reason_len > 0)) {
			unsigned int i;

			for (i = 0; i < reason_len; i++) {
				char tmp[100];

				lrtr_ip_addr_to_str(&reason[i].prefix,
						    tmp, sizeof(tmp));
				printf("%u %s %u %u",
				       reason[i].asn, tmp,
				       reason[i].min_len,
				       reason[i].max_len);
				if ((i + 1) < reason_len)
					printf(",");
			}
		}

		/* |validity_code */
		printf("|%d", validity_code);

		printf("\n");
		fflush(stdout);
	}

	rtr_mgr_stop(conf);
	rtr_mgr_free(conf);
	free(groups[0].sockets);

	return EXIT_SUCCESS;
}