Exemplo n.º 1
0
controller::controller(std::string pyton_config_file_)
// can not init init list form r vals, hence lmbd hack
    :	buffers       {	[]{	std::vector<std::unique_ptr<buffer>> b;
    b.push_back(util::make_unique<log_buffer>("status"));
    return b;
}()
                }
,	view              { io_service, *buffers[0]           }
#ifdef USING_PYTHON
,	python_controller { std::move(pyton_config_file_)  }
#endif //USING_PYTHON
{
    auto username=util::try_get_user_name();
    if(username) {
        default_username=*username;
        default_nick=std::move(*username);
    }
    auto fullname=util::try_get_full_name();
    if(fullname) default_fullname=std::move(*fullname);

    view.connect_on_text_input(
        std::bind(&controller::handle_text_input, this, ph::_1));

    view.connect_on_ctrl_char(
        std::bind(&controller::handle_ctrl_char, this, ph::_1));

#ifdef USING_PYTHON
    python_controller.connect_on_connect(
    [this](const std::string& server) {
        start_connection(server);
    });
    python_controller.connect_on_change_default_nick(
        util::make_assign_on_call(default_nick));
    python_controller.connect_on_change_default_username(
        util::make_assign_on_call(default_username));
    python_controller.connect_on_change_default_fullname(
        util::make_assign_on_call(default_fullname));
    python_controller.connect_on_python_error(
    [this](const std::string s) {
        if(show_errors) {
            auto& status_buf=get_status_buffer();
            std::ostringstream oss;
            oss << "PYTHON ERROR: " << s;
            status_buf.push_back_msg(oss.str());
        }
    }
    );
    python_controller.connect_on_python_output(
    [this](const std::string s) {
        auto& status_buf=get_status_buffer();
        std::ostringstream oss;
        oss << "PYTHON: " << s;
        status_buf.push_back_msg(oss.str());
    }
    );
    python_controller.reload_conf();
#endif //USING_PYTHON

    set_channels();
}
Exemplo n.º 2
0
int main(){


	signal(SIGALRM, timer_handler);


	in_port_t server_portno = SERVER_PORT_NO;


	if( (main_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
		perror("Error: Creating the main socket");
		return EXIT_FAILURE;
	}

	// setting server_addr
	memset((char *)&server_addr, 0, sizeof(server_addr));// initialization
	// 0 init is important since the server_addr.zero[] must be zero
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	server_addr.sin_port = htons(server_portno);

	// setting client_addr
	memset((char *) &client_addr, 0, client_addr_len);

	if ( (bind(main_sock, (struct sockaddr*) &server_addr, sizeof(server_addr)))  < 0){
		perror("ERROR on binding socket to server address");
		return EXIT_FAILURE;
	}

	int worker_pid;
	while (1) {

		// receive request
		// since we know the server the request message only contains the file path/name : my protocol my rules :P
		recvfrom(main_sock, file_name, sizeof(file_name), 0, (struct sockaddr*) &client_addr, &client_addr_len);
		printf("requested file is: %s\n",file_name);

		if ( (worker_pid = fork()) < 0) {
			perror("ERROR on forking a new worker process");
			continue;
		}

		if (!worker_pid) { // worker_pid = 0 then we are in the child
			// create the working socket
			close(main_sock);
			if ( (worker_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
				perror("Error: Creating the worker socket");
				return EXIT_FAILURE;
			}

			signal(SIGALRM, timer_handler);
			start_connection();
			exit(EXIT_SUCCESS);
		} else { // pid != 0 then we are in the parent;
			close(worker_sock);
		}

	}
	return EXIT_SUCCESS;
}
Exemplo n.º 3
0
cql_ccm_bridge_t::cql_ccm_bridge_t(const cql_ccm_bridge_configuration_t& settings)
  : _ip_prefix(settings.ip_prefix())
  , _cassandra_version(settings.cassandara_version())
  , _socket(-1)
  , _ssh_internals(new ssh_internals()) {
  initialize_socket_library();

  try {
    // initialize libssh2 - not thread safe
    if (0 != libssh2_init(0))
      throw cql_ccm_bridge_exception_t("cannot initialize libssh2 library");

    try {
      start_connection(settings);

      try {
        start_ssh_connection(settings);
      } catch (cql_ccm_bridge_exception_t&) {
        close_socket();
        throw;
      }
    } catch (cql_ccm_bridge_exception_t&) {
      libssh2_exit();
      throw;
    }
  } catch (cql_ccm_bridge_exception_t&) {
    finalize_socket_library();
    throw;
  }

  initialize_environment();
}
Exemplo n.º 4
0
static lcb_error_t http_connect(lcb_t instance)
{
    lcb_error_t ret;
    lcb_error_callback old_cb;
    lcb_connection_t conn = &instance->bootstrap.via.http.connection;

    if (instance->compat.type == LCB_MEMCACHED_CLUSTER ||
        (instance->compat.type == LCB_CACHED_CONFIG &&
         instance->config.handle != NULL &&
         instance->compat.value.cached.updating == 0)) {
        return LCB_SUCCESS;
    }
    switch (conn->state) {
    case LCB_CONNSTATE_CONNECTED:
        return LCB_SUCCESS;
    case LCB_CONNSTATE_INPROGRESS:
        return LCB_BUSY;
    default:
        old_cb = instance->callbacks.error;
        instance->callbacks.error = dummy_error_callback;
        ret = start_connection(instance);
        instance->callbacks.error = old_cb;
        return ret;
    }
}
Exemplo n.º 5
0
/* Return 0 if we sent something, non-0 otherwise.
   If 0 is returned, the caller should delay waiting for a response.
   Otherwise, the caller should immediately move on to process the
   next connection.  */
static int
maybe_send(krb5_context context, struct conn_state *conn,
           struct select_state *selstate,
           struct sendto_callback_info *callback_info)
{
    sg_buf *sg;
    ssize_t ret;

    dprint("maybe_send(@%p) state=%s type=%s\n", conn,
           state_strings[conn->state],
           conn->is_udp ? "udp" : "tcp");
    if (conn->state == INITIALIZING)
        return start_connection(context, conn, selstate, callback_info);

    /* Did we already shut down this channel?  */
    if (conn->state == FAILED) {
        dprint("connection already closed\n");
        return -1;
    }

    if (conn->socktype == SOCK_STREAM) {
        dprint("skipping stream socket\n");
        /* The select callback will handle flushing any data we
           haven't written yet, and we only write it once.  */
        return -1;
    }

    /* UDP - retransmit after a previous attempt timed out. */
    sg = &conn->x.out.sgbuf[0];
    TRACE_SENDTO_KDC_UDP_SEND_RETRY(context, conn);
    dprint("sending %d bytes on fd %d\n", SG_LEN(sg), conn->fd);
    ret = send(conn->fd, SG_BUF(sg), SG_LEN(sg), 0);
    if (ret < 0 || (size_t) ret != SG_LEN(sg)) {
        TRACE_SENDTO_KDC_UDP_ERROR_SEND_RETRY(context, conn, SOCKET_ERRNO);
        dperror("send");
        /* Keep connection alive, we'll try again next pass.

           Is this likely to catch any errors we didn't get from the
           select callbacks?  */
        return -1;
    }
    /* Yay, it worked.  */
    return 0;
}
Exemplo n.º 6
0
/* Return 0 if we sent something, non-0 otherwise.
   If 0 is returned, the caller should delay waiting for a response.
   Otherwise, the caller should immediately move on to process the
   next connection.  */
static int
maybe_send(krb5_context context, struct conn_state *conn,
           const krb5_data *message, struct select_state *selstate,
           const krb5_data *realm,
           struct sendto_callback_info *callback_info)
{
    sg_buf *sg;
    ssize_t ret;

    if (conn->state == INITIALIZING) {
        return start_connection(context, conn, message, selstate,
                                realm, callback_info);
    }

    /* Did we already shut down this channel?  */
    if (conn->state == FAILED) {
        return -1;
    }

    if (conn->addr.transport != UDP) {
        /* The select callback will handle flushing any data we
           haven't written yet, and we only write it once.  */
        return -1;
    }

    /* UDP - retransmit after a previous attempt timed out. */
    sg = &conn->out.sgbuf[0];
    TRACE_SENDTO_KDC_UDP_SEND_RETRY(context, &conn->addr);
    ret = send(conn->fd, SG_BUF(sg), SG_LEN(sg), 0);
    if (ret < 0 || (size_t) ret != SG_LEN(sg)) {
        TRACE_SENDTO_KDC_UDP_ERROR_SEND_RETRY(context, &conn->addr,
                                              SOCKET_ERRNO);
        /* Keep connection alive, we'll try again next pass.

           Is this likely to catch any errors we didn't get from the
           select callbacks?  */
        return -1;
    }
    /* Yay, it worked.  */
    return 0;
}
Exemplo n.º 7
0
int
main (int argc, char **argv)
{
  struct hostent *hp;
  int            optc;
  int            not_inetd = 0;
  char           buf[BDM_SERVER_BUF_SIZE];
  int            cread;

  program_name = argv[0];

  while ((optc = getopt (argc, argv, "dnVh")) != EOF)
  {
    switch (optc)
    {
      case 'd':
        debug++;
        break;

      case 'n':
        not_inetd = 1;
        break;

      case 'V':
        version ();
        exit (0);
        break;

      case 'h':
      default:
        usage ();
    }
  }

  /*
   * Process options.
   */

  umask (022);

  /*
   * chdir
   */

  fflush (stderr);
  fflush (stdout);

  closelog ();

#ifdef LOG_DAEMON
  openlog ("bdmd", (LOG_PID|LOG_CONS), LOG_DAEMON);
#else
  openlog ("bdmd", LOG_PID);
#endif

  if (gethostname (myname, MAXHOSTNAMELEN)) {
    fprintf (stderr, "%s: cannot find out the name of this host\n",
             program_name);
    exit (1);
  }

  myname[MAXHOSTNAMELEN - 1] = 0;

  /*
   * Now see if we can get a FQDN for this host.
   */

  hp = gethostbyname (myname);
  if (hp && (strlen (hp->h_name) > strlen (myname)))
    strncpy (myname, hp->h_name, MAXHOSTNAMELEN);
  myname[MAXHOSTNAMELEN - 1] = 0;

  bdmLogSyslog ();

  /*
   * Don't pay attention to SIGPIPE; read will give us the problem
   * if it happens.
   */

  signal (SIGPIPE, SIG_IGN);

  if (!not_inetd)
    start_connection ();
  else
  {
    current_host = myname;
    if (hp)
      current_addr = (char *) inet_ntoa (*(struct in_addr *) hp->h_addr);
    else
      current_addr = myname;
  }

  if (debug)
    syslog (LOG_INFO, "host connected: %s (%s)", current_host, current_addr);

  /*
   * Say hello to the remote end. It will be waiting.
   */

  while (1) {
    cread = get_message (buf, BDM_SERVER_BUF_SIZE);

    if (cread == 0) {
      break;
    }

    if (cread > 0) {
      if (debug > 1) {
        int len = strlen (buf);
        syslog (LOG_INFO, "msg: %s", buf);
        if (len>900)
          syslog (LOG_INFO, "msg end: %s", buf + len - 100);
      }

      process_message (buf, cread, BDM_SERVER_BUF_SIZE);

      fflush (stdout);
    }
  }

  bdmClose ();

  return 0;
}
Exemplo n.º 8
0
int
main( int argc, char** argv )
    {
    int argn;
    int start;
#define START_NONE 0
#define START_PARALLEL 1
#define START_RATE 2
    int start_parallel = -1, start_rate = -1;
    int end;
#define END_NONE 0
#define END_FETCHES 1
#define END_SECONDS 2
    int end_fetches = -1, end_seconds = -1;
    int cnum;
    char* url_file;
    char* sip_file;
#ifdef RLIMIT_NOFILE
    struct rlimit limits;
#endif /* RLIMIT_NOFILE */
    fd_set rfdset;
    fd_set wfdset;
    struct timeval now;
    int i, r;

    max_connections = 64 - RESERVED_FDS;	/* a guess */
#ifdef RLIMIT_NOFILE
    /* Try and increase the limit on # of files to the maximum. */
    if ( getrlimit( RLIMIT_NOFILE, &limits ) == 0 )
	{
	if ( limits.rlim_cur != limits.rlim_max )
	    {
	    if ( limits.rlim_max == RLIM_INFINITY )
		limits.rlim_cur = 8192;		/* arbitrary */
	    else if ( limits.rlim_max > limits.rlim_cur )
		limits.rlim_cur = limits.rlim_max;
	    (void) setrlimit( RLIMIT_NOFILE, &limits );
	    }
	max_connections = limits.rlim_cur - RESERVED_FDS;
	}
#endif /* RLIMIT_NOFILE */

    /* Parse args. */
    argv0 = argv[0];
    argn = 1;
    do_checksum = do_throttle = do_verbose = do_jitter = do_proxy = 0;
    throttle = THROTTLE;
    sip_file = (char*) 0;
    idle_secs = IDLE_SECS;
    start = START_NONE;
    end = END_NONE;
    while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
	{
	if ( strncmp( argv[argn], "-checksum", strlen( argv[argn] ) ) == 0 )
	    do_checksum = 1;
	else if ( strncmp( argv[argn], "-throttle", strlen( argv[argn] ) ) == 0 )
	    do_throttle = 1;
	else if ( strncmp( argv[argn], "-Throttle", strlen( argv[argn] ) ) == 0 && argn + 1 < argc )
	    {
	    do_throttle = 1;
	    throttle = atoi( argv[++argn] ) / 10.0;
	    }
	else if ( strncmp( argv[argn], "-verbose", strlen( argv[argn] ) ) == 0 )
	    do_verbose = 1;
	else if ( strncmp( argv[argn], "-timeout", strlen( argv[argn] ) ) == 0 && argn + 1 < argc )
	    idle_secs = atoi( argv[++argn] );
	else if ( strncmp( argv[argn], "-jitter", strlen( argv[argn] ) ) == 0 )
	    do_jitter = 1;
	else if ( strncmp( argv[argn], "-parallel", strlen( argv[argn] ) ) == 0 && argn + 1 < argc )
	    {
	    start = START_PARALLEL;
	    start_parallel = atoi( argv[++argn] );
	    if ( start_parallel < 1 )
		{
		(void) fprintf(
		    stderr, "%s: parallel must be at least 1\n", argv0 );
		exit( 1 );
		}
	    if ( start_parallel > max_connections )
		{
		(void) fprintf(
		    stderr, "%s: parallel may be at most %d\n", argv0, max_connections );
		exit( 1 );
		}
	    }
	else if ( strncmp( argv[argn], "-rate", strlen( argv[argn] ) ) == 0 && argn + 1 < argc )
	    {
	    start = START_RATE;
	    start_rate = atoi( argv[++argn] );
	    if ( start_rate < 1 )
		{
		(void) fprintf(
		    stderr, "%s: rate must be at least 1\n", argv0 );
		exit( 1 );
		}
	    if ( start_rate > 1000 )
		{
		(void) fprintf(
		    stderr, "%s: rate may be at most 1000\n", argv0 );
		exit( 1 );
		}
	    }
	else if ( strncmp( argv[argn], "-fetches", strlen( argv[argn] ) ) == 0 && argn + 1 < argc )
	    {
	    end = END_FETCHES;
	    end_fetches = atoi( argv[++argn] );
	    if ( end_fetches < 1 )
		{
		(void) fprintf(
		    stderr, "%s: fetches must be at least 1\n", argv0 );
		exit( 1 );
		}
	    }
	else if ( strncmp( argv[argn], "-seconds", strlen( argv[argn] ) ) == 0 && argn + 1 < argc )
	    {
	    end = END_SECONDS;
	    end_seconds = atoi( argv[++argn] );
	    if ( end_seconds < 1 )
		{
		(void) fprintf(
		    stderr, "%s: seconds must be at least 1\n", argv0 );
		exit( 1 );
		}
	    }
	else if ( strncmp( argv[argn], "-sip", strlen( argv[argn] ) ) == 0 && argn + 1 < argc )
	    sip_file = argv[++argn];
#ifdef USE_SSL
	else if ( strncmp( argv[argn], "-cipher", strlen( argv[argn] ) ) == 0 && argn + 1 < argc )
	    {
	    cipher = argv[++argn];
	    if ( strcasecmp( cipher, "fastsec" ) == 0 )
		cipher = "RC4-MD5";
	    else if ( strcasecmp( cipher, "highsec" ) == 0 )
		cipher = "DES-CBC3-SHA";
	    else if ( strcasecmp( cipher, "paranoid" ) == 0 )
		cipher = "AES256-SHA";
	    }
#endif /* USE_SSL */
	else if ( strncmp( argv[argn], "-proxy", strlen( argv[argn] ) ) == 0 && argn + 1 < argc )
	    {
	    char* colon;
	    do_proxy = 1;
	    proxy_hostname = argv[++argn];
	    colon = strchr( proxy_hostname, ':' );
	    if ( colon == (char*) 0 )
		proxy_port = 80;
	    else
		{
		proxy_port = (unsigned short) atoi( colon + 1 );
		*colon = '\0';
		}
	    }
	else
	    usage();
	++argn;
	}
    if ( argn + 1 != argc )
	usage();
    if ( start == START_NONE || end == END_NONE )
	usage();
    if ( do_jitter && start != START_RATE )
	usage();
    url_file = argv[argn];

    /* Read in and parse the URLs. */
	printf("Loading url file...");
    read_url_file( url_file );
	printf("Total %d urls loaded.\n", num_urls);

    /* Read in the source IP file, if specified. */
    if ( sip_file != (char*) 0 )
	read_sip_file( sip_file );

    /* Initialize the connections table. */
    if ( start == START_PARALLEL )
	max_connections = start_parallel;
    connections = (connection*) malloc_check(
	max_connections * sizeof(connection) );
    for ( cnum = 0; cnum < max_connections; ++cnum )
	connections[cnum].conn_state = CNST_FREE;
    num_connections = max_parallel = 0;

    /* Initialize the HTTP status-code histogram. */
    for ( i = 0; i < 1000; ++i )
	http_status_counts[i] = 0;

    /* Initialize the statistics. */
    fetches_started = 0;
    connects_completed = 0;
    responses_completed = 0;
    fetches_completed = 0;
    total_bytes = 0;
    total_connect_usecs = 0;
    max_connect_usecs = 0;
    min_connect_usecs = 1000000000L;
    total_response_usecs = 0;
    max_response_usecs = 0;
    min_response_usecs = 1000000000L;
    total_timeouts = 0;
    total_badbytes = 0;
    total_badchecksums = 0;

    /* Initialize the random number generator. */
#ifdef HAVE_SRANDOMDEV
    srandomdev();
#else
    srandom( (int) time( (time_t*) 0 ) ^ getpid() );
#endif

    /* Initialize the rest. */
    tmr_init();
    (void) gettimeofday( &now, (struct timezone*) 0 );
    start_at = now;
    if ( do_verbose )
	(void) tmr_create(
	    &now, progress_report, JunkClientData, PROGRESS_SECS * 1000L, 1 );
    if ( start == START_RATE )
	{
	start_interval = 1000L / start_rate;
	if ( do_jitter )
	    {
	    low_interval = start_interval * 9 / 10;
	    high_interval = start_interval * 11 / 10;
	    range_interval = high_interval - low_interval + 1;
	    }
	(void) tmr_create(
	    &now, start_timer, JunkClientData, start_interval, ! do_jitter );
	}
    if ( end == END_SECONDS )
	(void) tmr_create(
	    &now, end_timer, JunkClientData, end_seconds * 1000L, 0 );
    (void) signal( SIGPIPE, SIG_IGN );

    /* Main loop. */
    for (;;)
	{
	if ( end == END_FETCHES && fetches_completed >= end_fetches )
	    finish( &now );

	if ( start == START_PARALLEL )
	    {
	    /* See if we need to start any new connections; but at most 10. */
	    for ( i = 0;
		  i < 10 &&
		    num_connections < start_parallel &&
		    ( end != END_FETCHES || fetches_started < end_fetches );
		  ++i )
		{
		start_connection( &now );
		(void) gettimeofday( &now, (struct timezone*) 0 );
		tmr_run( &now );
		}
	    }

	/* Build the fdsets. */
	FD_ZERO( &rfdset );
	FD_ZERO( &wfdset );
	for ( cnum = 0; cnum < max_connections; ++cnum )
	    switch ( connections[cnum].conn_state )
		{
		case CNST_CONNECTING:
		FD_SET( connections[cnum].conn_fd, &wfdset );
		break;
		case CNST_HEADERS:
		case CNST_READING:
		FD_SET( connections[cnum].conn_fd, &rfdset );
		break;
		}
	r = select(
	    FD_SETSIZE, &rfdset, &wfdset, (fd_set*) 0, tmr_timeout( &now ) );
	if ( r < 0 )
	    {
	    perror( "select" );
	    exit( 1 );
	    }
	(void) gettimeofday( &now, (struct timezone*) 0 );

	/* Service them. */
	for ( cnum = 0; cnum < max_connections; ++cnum )
	    switch ( connections[cnum].conn_state )
		{
		case CNST_CONNECTING:
		if ( FD_ISSET( connections[cnum].conn_fd, &wfdset ) )
		    handle_connect( cnum, &now, 1 );
		break;
		case CNST_HEADERS:
		case CNST_READING:
		if ( FD_ISSET( connections[cnum].conn_fd, &rfdset ) )
		    handle_read( cnum, &now );
		break;
		}
	/* And run the timers. */
	tmr_run( &now );
	}

    /* NOT_REACHED */
    }
Exemplo n.º 9
0
int main(void)
{
  system(CLEAR_SC);

  /* Creation/Load of the database */

  database = open ("database", O_RDWR | O_CREAT,S_IRWXU);

  if(database==ERROR)
    return ERROR;

  /* Initialize the flock structure. */
  lock.l_type = F_WRLCK; /* A write lock also blocks readers */
  lock.l_start = 0;
  lock.l_len = 0;
  lock.l_whence = SEEK_SET;

  /* Lock the database */

  printf("Accesing the database\n");

  if(fcntl (database, F_SETLKW, &lock)==ERROR)
    return ERROR;

  printf("Access granted\n");

  /* Assign handler for SIGINT (AKA Ctl+C) */
  struct sigaction sa;
  memset (&sa, 0, sizeof (sa));

  sa.sa_handler=&sigint_handler;

  if(sigaction(SIGINT,&sa,NULL)==-1)
    return SIGNAL_ERROR;

  /*Binary semaphore creation - MUTEX*/

  semaphore=binary_semaphore_allocation(IPC_PRIVATE,IPC_CREAT);
  binary_semaphore_initialize(semaphore);

  /*Shared Memory Allocation*/

  users_shared_memory = shmget(IPC_PRIVATE,sizeof(data_person)*MAX_USERS,IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR );
  newid_shared_memory = shmget(IPC_PRIVATE,sizeof(int),IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR );

  /* Shared Memory Attach */
  int * newid = (int *) shmat(newid_shared_memory,0,0);

  data_person * users = (data_person *) shmat(users_shared_memory,0,0);

  /* Shared Memory initialization */
  *newid=0;

  /* Load data from the database */
  load_database(users,newid);

  /* Shared Memory Detach */
  shmdt(newid);
  shmdt(users);

  /*Client-Server comunication*/
  if(initialize()==ERROR)
  {
    printf("The port 49500 was not available\n");
    sigint_handler(0);
  }

  start_connection(&application_request,MAX_QUEUE);

  return 0;
}
Exemplo n.º 10
0
void controller::start_connection(const std::string& hostname) {
    start_connection(hostname, get_default_nick(), get_default_username(),
                     get_default_fullname(), get_default_port());
}
Exemplo n.º 11
0
void controller::handle_connect(const std::string& chan) {
    start_connection(chan);
}
void process_inbound_udp(int sock) {
    struct sockaddr_in from;
    socklen_t fromlen;
    char buf[MAX_PACKET_LENGTH];

    fromlen = sizeof(from);
    int read_result = spiffy_recvfrom(sock, buf, MAX_PACKET_LENGTH, 0, (struct sockaddr *) &from, &fromlen);
    printf("read %d bytes\n", read_result);
    //printf("incoming message from %s:%d\n", inet_ntoa(from.sin_addr), ntohs(from.sin_port));

    /* we just assume we got one packet everytime
     * if there are multiple packets in the buffer (whichi is rare), we just ignore them,
     * and everything will just work fine.
     */
    struct network_packet_s* network_packet = (struct network_packet_s*)buf;
    net_to_host_header(& network_packet->header);
    print_packet_header(&network_packet->header);
    if(validate_packet(& network_packet->header) < 0){
        printf("packet is invalid, skip\n");
        return;
    }
    int packet_type = get_packet_type(& network_packet->header);
    /* get the peer who send this packet*/
    bt_peer_t* peer = search_bt_peer(&config, (struct sockaddr *)&from);
    switch(packet_type) {
        case TYPE_WHOHAS: {
            struct network_packet_s* ihave_packet = malloc_ihave_packet(network_packet);
            /* this node has no such chunk */
            if(ihave_packet == NULL){
                return;
            }
            else{
                //print_ihave_packet(ihave_packet);
                send_packet(ihave_packet, global_socket, (struct sockaddr *) &from);
                free(ihave_packet);
            }
            break;
        }
        case TYPE_IHAVE: {
            if(current_job == NULL){
                return;
            }
            /* receiving a new IHAVE packet */
            /* check whether there is alreay a connection with this peer */
            struct receiver_connection_s* existing_connection = 
                    search_receiver_connection(receiver_connection_head, peer);
            if(existing_connection != NULL){
            /* there is alreay a connection */
                add_ihave_to_receiver_connection(existing_connection, network_packet);
            }
            /* there is no such connection */
            else{
                /* check if the number of connection reached the maximum */
                if(get_receiver_connection_number(receiver_connection_head) >=
                        max_receiver_connection){
                    return;
                }
                /* add add the hash whose chunk is in a CHUNK_STATUS_NOT_FOUND status 
                 * to a new connection
                 */
                else{
                    struct receiver_connection_s*  new_connection = 
                        malloc_receiver_connection(network_packet, peer);
                    /* if every chunk has a provider, the new_connection is NULL */
                    if(new_connection != NULL){
                        add_receiver_connection(new_connection);
                        /* start the new connection */
                        struct network_packet_s* get_packet = start_connection(new_connection);
                        //print_get_packet(get_packet);
                        free(get_packet);
                    }   
                }
            }
            //print_receiver_connection_list(receiver_connection_head);
            break;
        }
        case TYPE_GET: {
            //print_get_packet(network_packet);
            /* check whether there is alreay a connection with this peer */
            if(search_provider_connection(provider_connection_head, peer) != NULL){
                printf("Provider connection already exists with peer %d , ignore GET\n", peer->id);
                return;
            }
            /* do nothing is the number of connection reached the maximum*/
            if(get_provider_connection_number(provider_connection_head) >=
                    max_provider_connection){
                printf("Provider connection reached maximum with peer %d \n", peer->id);
                return;
            }
            struct provider_connection_s* new_connection = 
                    malloc_provider_connection(network_packet, peer);
            if(new_connection != NULL){
                printf("Add new provider connection with peer %d \n", peer->id);
                add_provider_connection(new_connection);
                //print_provider_connection(new_connection);
            }
            //print_provider_connection_list(provider_connection_head);
            break;
        }
        case TYPE_DATA: {
            print_data_packet(network_packet);
            printf("received data packet, seq: %d, ack: %d\n ",
                network_packet->header.seq_number,
                network_packet->header.ack_number);

            /* check whether there is a connection with this peer */
            struct receiver_connection_s* receiver_connection = 
                    search_receiver_connection(receiver_connection_head, peer);
            /* connection does not exist, ignore the data packet */
            if(receiver_connection == NULL){
                return;
            }
            int existing_seq_num = receiver_connection->chunk_list_head->chunk->received_seq_num;
            printf("expected data packet, seq: %d \n", 1 + existing_seq_num);
            int packet_seq_num = network_packet->header.seq_number;
            /* sequence number is illegal */
            if(packet_seq_num < 0){
                return;
            }
            /* old packet arrived, do nothing */
            else if(packet_seq_num  < (existing_seq_num + 1)){
                return;
            } 
            /* latter packet arrived first, send duplicate ACK */
            else if(packet_seq_num  > (existing_seq_num + 1)){
                struct network_packet_s* ack_packet = malloc_ack_packet(existing_seq_num);
                send_packet(ack_packet, global_socket, (struct sockaddr *) &from);
                free(ack_packet);
                return;
            }
            /* the packet expected */
            else{
                gettimeofday(&receiver_connection->last_data_time, NULL);
                receiver_connection->status = RECEIVER_STATUS_RECEIVED_DATA;

                struct network_packet_s* ack_packet = malloc_ack_packet(1 + existing_seq_num);
                send_packet(ack_packet, global_socket, (struct sockaddr *) &from);
                free(ack_packet);
                
                /* save_data_packet */
                save_data_packet(network_packet, receiver_connection);
                /* save the downloading chunk of the connnection, if it finihsed */
                save_chunk(receiver_connection);
                /* continue to download next chunk, if finished first one */
                reset_receiver_connection(receiver_connection);
            } 
            break;
        }
        case TYPE_ACK: {
            //print_ack_packet(network_packet);
            struct provider_connection_s* provider_connection = 
                    search_provider_connection(provider_connection_head, peer);
            if(provider_connection == NULL){
                return;
            }
            provider_control_by_ack(provider_connection, 
                    network_packet->header.ack_number);
            /* check if the data has been all send to a receiver */
            if(provider_connection->last_packet_acked == CHUNK_DATA_NUM){
                /* download finished */
                finish_provider_connection(provider_connection);
            }
            break;
        }
        case TYPE_DENIED: {
            break;
        }
        default:{
            break;
        }
    }
}