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(); }
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; }
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(); }
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; } }
/* 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; }
/* 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; }
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; }
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 */ }
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; }
void controller::start_connection(const std::string& hostname) { start_connection(hostname, get_default_nick(), get_default_username(), get_default_fullname(), get_default_port()); }
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; } } }