/************************************************************************ * NAME: fapp_mem_erase_cmd * * DESCRIPTION: ************************************************************************/ void fapp_mem_erase_cmd ( fnet_shell_desc_t desc, fnet_index_t argc, fnet_char_t ** argv ) { fnet_uint32_t address; fnet_size_t size; fnet_char_t *p; fnet_return_t result; FNET_COMP_UNUSED_ARG(desc); fnet_shell_println(desc, "Erasing..."); if (argc == 3u) { address = fnet_strtoul(argv[1],&p,16u); if ((address == 0u) && (p == argv[1])) { fnet_shell_println(desc, FAPP_PARAM_ERR, argv[1] ); return; } size = fnet_strtoul(argv[2],&p,10u); if ((size == 0u) && (p == argv[2])) { fnet_shell_println(desc, FAPP_PARAM_ERR, argv[2] ); return; } result = fapp_mem_erase( (void *)address, size); if( result == FNET_OK) { fnet_shell_println(desc, FAPP_MEM_ERASE_ERASED, address, address+size-1u ); } else { fnet_shell_println(desc, FAPP_MEM_ERASE_FAILED, address, address+size-1u ); } } else if ((argc == 2u) && (fnet_strcasecmp(FAPP_MEM_ERASE_ALL, argv[1]) == 0)) /* Erase all */ { fapp_mem_erase_all(desc); } else { fnet_shell_println(desc, FAPP_PARAM_ERR, argv[1]); } }
/************************************************************************ * NAME: fapp_mem_erase_cmd * * DESCRIPTION: ************************************************************************/ void fapp_mem_erase_cmd ( fnet_shell_desc_t desc, int argc, char ** argv ) { unsigned long address; unsigned long size; char *p; int result; FNET_COMP_UNUSED_ARG(desc); fnet_shell_println(desc, "Erasing..."); if (argc == 3) { address = fnet_strtoul(argv[1],&p,16); if ((address == 0) && (p == argv[1])) { fnet_shell_println(desc, FAPP_PARAM_ERR, argv[1] ); return; } size = fnet_strtoul(argv[2],&p,10); if ((size == 0) && (p == argv[2])) { fnet_shell_println(desc, FAPP_PARAM_ERR, argv[2] ); return; } result = fapp_mem_erase( (void *)address, size); if( result == FNET_OK) fnet_shell_println(desc, FAPP_MEM_ERASE_ERASED, address, address+size-1 ); else fnet_shell_println(desc, FAPP_MEM_ERASE_FAILED, address, address+size-1 ); } else if ((argc == 2) && fnet_strcasecmp(FAPP_MEM_ERASE_ALL, argv[1]) == 0) /* Erase all */ { fapp_mem_erase_all(desc); } else { fnet_shell_println(desc, FAPP_PARAM_ERR, argv[1]); } }
static void fapp_set_cmd_raw(fnet_shell_desc_t desc, char *value ) { unsigned long address; char *p = 0; address = fnet_strtoul(value,&p,16); if ((address == 0) && (p == value)) fnet_shell_println(desc, FAPP_PARAM_ERR, value); /* Print error mesage. */ else fapp_params_tftp_config.file_raw_address = address; }
static void fapp_set_cmd_bootdelay(fnet_shell_desc_t desc, char *value ) { unsigned long delay; char *p = 0; delay = fnet_strtoul(value,&p,0); if ((delay == 0) && (p == value)) fnet_shell_println(desc, FAPP_PARAM_ERR, value); /* Print error mesage. */ else fapp_params_boot_config.delay = delay; }
void fapp_go_cmd ( fnet_shell_desc_t desc, fnet_index_t argc, fnet_char_t **argv ) { fnet_uint32_t address; fnet_char_t *p; if (argc == 2u) { address = fnet_strtoul(argv[1],&p,16u); if (p == argv[1]) { fnet_shell_println(desc, FAPP_PARAM_ERR, argv[1] ); return; } } else { address = fapp_params_boot_config.go_address; } fapp_go(desc, address); }
/************************************************************************ * NAME: fnet_inet_ptos * * DESCRIPTION:The function converts from presentation format (string) * to struct sockaddr. *************************************************************************/ int fnet_inet_ptos (const char *str, struct sockaddr *addr) { #if FNET_CFG_IP4 if(fnet_inet_pton(AF_INET, str, addr->sa_data, sizeof(addr->sa_data)) == FNET_OK) { addr->sa_family = AF_INET; } else #endif /* FNET_CFG_IP4 */ #if FNET_CFG_IP6 if(fnet_inet_pton(AF_INET6, str, addr->sa_data, sizeof(addr->sa_data)) == FNET_OK) { addr->sa_family = AF_INET6; /* Scope ID.*/ { unsigned long scope_id; const char *p = fnet_strrchr(str, '%'); /* Find "%<scope id>".*/ if(p != FNET_NULL) { scope_id = fnet_strtoul((p+1), 0, 10); } else { scope_id = 0; /* Default interface.*/ } ((struct sockaddr_in6 *)addr)->sin6_scope_id = scope_id; } } else #endif /* FNET_CFG_IP6 */ return FNET_ERR; addr->sa_port = 0; return FNET_OK; }
/************************************************************************ * NAME: fapp_benchtx_cmd * * DESCRIPTION: Start TX Benchmark. ************************************************************************/ void fapp_benchtx_cmd( fnet_shell_desc_t desc, int argc, char ** argv ) { struct fapp_bench_tx_params bench_params; fnet_memset_zero(&bench_params.foreign_addr, sizeof(bench_params.foreign_addr)); if(fnet_inet_ptos(argv[1], &bench_params.foreign_addr) == FNET_OK) { bench_params.desc = desc; bench_params.foreign_addr.sa_port = FAPP_BENCH_PORT; bench_params.packet_size = FAPP_BENCH_TX_PACKET_SIZE_DEFAULT; bench_params.packet_number = FAPP_BENCH_TX_PACKET_NUMBER_DEFAULT; bench_params.iteration_number = FAPP_BENCH_TX_ITERATION_NUMBER_DEFAULT; if(argc > 3) { char *p = 0; /* Packet size.*/ bench_params.packet_size = (int)fnet_strtoul(argv[3], &p, 0); if ((bench_params.packet_size == 0) || (bench_params.packet_size > FAPP_BENCH_PACKET_SIZE_MAX)) { fnet_shell_println(desc, FAPP_PARAM_ERR, argv[3]); /* Print error mesage. */ return; } /* Number of packets.*/ if(argc > 4) { bench_params.packet_number = (int)fnet_strtoul(argv[4], &p, 0); if (bench_params.packet_number == 0) { fnet_shell_println(desc, FAPP_PARAM_ERR, argv[4]); /* Print error mesage. */ return; } /* Number of iterations.*/ if(argc > 5) { bench_params.iteration_number = (int)fnet_strtoul(argv[5], &p, 0); if ((bench_params.iteration_number < 1) || (bench_params.iteration_number > FAPP_BENCH_TX_ITERATION_NUMBER_MAX) ) { fnet_shell_println(desc, FAPP_PARAM_ERR, argv[5]); /* Print error mesage. */ return; } } } } /* TCP */ if((argc == 2)||(argc >= 3 && fnet_strcasecmp("tcp", argv[2]) == 0)) { fapp_bench_tcp_tx (&bench_params); } /* UDP */ else if(argc >= 3 && fnet_strcasecmp("udp", argv[2]) == 0) { fapp_bench_udp_tx (&bench_params); } else { fnet_shell_println(desc, FAPP_PARAM_ERR, argv[2]); } } else { fnet_shell_println(desc, FAPP_PARAM_ERR, argv[1]); /* Wrong Benchmark Server IP address. */ return; } }
/************************************************************************ * NAME: fapp_ping_cmd * * DESCRIPTION: Ping command. ************************************************************************/ void fapp_ping_cmd( fnet_shell_desc_t desc, fnet_index_t argc, fnet_char_t ** argv ) { struct fnet_ping_params ping_params; fnet_index_t i; fnet_char_t *p; fnet_uint32_t value; fnet_char_t ip_str[FNET_IP_ADDR_STR_SIZE]; fnet_memset_zero(&ping_params, sizeof(ping_params)); ping_params.cookie = (fnet_uint32_t)desc; ping_params.handler = fapp_ping_handler; ping_params.packet_size = FAPP_PING_DEFAULT_SIZE; ping_params.timeout = FAPP_PING_DEFAULT_TIMEOUT; ping_params.pattern = FAPP_PING_DEFAULT_PATTERN; ping_params.ttl = FAPP_PING_DEFAULT_HOP_LIMIT; ping_params.packet_count = FAPP_PING_DEFAULT_NUMBER; /* Last parameter must be ip address.*/ i = (argc-1u); if(fnet_inet_ptos(argv[i], &ping_params.target_addr) == FNET_ERR) { goto ERROR_PARAMETER; } else { /* TBD Optimise parameters parsing.*/ if(argc > 2u) /* There are additional parameters */ { /* [-c <count>][-i <seconds>]\n\t[-p <pattern>][-s <size>][-h <hoplimit/ttl>] */ for(i=1u; i<(fnet_index_t)(argc-1u); i++) { if (!fnet_strcmp(argv[i], "-c")) { i++; value = fnet_strtoul(argv[i], &p, 10u); if ((value == 0U) && (p == argv[i])) { goto ERROR_PARAMETER; } else { ping_params.packet_count = value; } } else if (!fnet_strcmp(argv[i], "-i")) { i++; value = fnet_strtoul(argv[i], &p, 10u); if ((value == 0U) && (p == argv[i])) { goto ERROR_PARAMETER; } else { ping_params.timeout = value*1000U; } } else if (!fnet_strcmp(argv[i], "-p")) { i++; value = fnet_strtoul(argv[i], &p, 10u); if ((value == 0U) && (p == argv[i])) { goto ERROR_PARAMETER; } else { ping_params.pattern = (fnet_uint8_t)value; } } else if (!fnet_strcmp(argv[i], "-s")) { i++; value = fnet_strtoul(argv[i], &p, 10u); if ((value == 0U) && (p == argv[i])) { goto ERROR_PARAMETER; } else { ping_params.packet_size = (fnet_size_t)value; } } else if (!fnet_strcmp(argv[i], "-h")) { i++; value = fnet_strtoul(argv[i], &p, 10u); if ((value == 0U) && (p == argv[i])) { goto ERROR_PARAMETER; } else { ping_params.ttl = (fnet_uint8_t)value; } } else if (!fnet_strcmp(argv[i], "-n")) { /* Just ignore the -n parameter.*/ } else if (!fnet_strcmp(argv[i], "-I")) { i++; /* Just ignore the -I parameter and its value.*/ } else /* Wrong parameter.*/ { goto ERROR_PARAMETER; } } } if(fnet_ping_request(&ping_params) == FNET_OK) { fnet_shell_println(desc, FAPP_DELIMITER_STR); fnet_shell_println(desc, " PING" ); fnet_shell_println(desc, FAPP_DELIMITER_STR); fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_S, "Remote IP addr", fnet_inet_ntop(ping_params.target_addr.sa_family, ping_params.target_addr.sa_data, ip_str, sizeof(ip_str))); fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_D, "Message Size", ping_params.packet_size>FNET_CFG_PING_PACKET_MAX?FNET_CFG_PING_PACKET_MAX:ping_params.packet_size); fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_D, "Num. of messages", ping_params.packet_count); fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_D, "Pattern", ping_params.pattern); fnet_shell_println(desc, FAPP_SHELL_INFO_FORMAT_D, "Hoplimit (TTL)", ping_params.ttl); fnet_shell_println(desc, FAPP_TOCANCEL_STR); fnet_shell_println(desc, FAPP_DELIMITER_STR); fnet_shell_block(desc, fapp_ping_on_ctrlc); /* Block shell. */ } else { fnet_shell_println(desc, FAPP_INIT_ERR, "PING"); } } return; ERROR_PARAMETER: fnet_shell_println(desc, FAPP_PARAM_ERR, argv[i]); return; }
/************************************************************************ * NAME: fnet_http_state_machine * * DESCRIPTION: Http server state machine. ************************************************************************/ static void fnet_http_state_machine( void *http_if_p ) { struct sockaddr foreign_addr; int len; int res; struct fnet_http_if *http = (struct fnet_http_if *)http_if_p; int iteration; char *ch; int i; struct fnet_http_session_if *session; for(i=0; i<FNET_CFG_HTTP_SESSION_MAX; i++) { session = &http->session[i]; http->session_active = session; for(iteration = 0; iteration < FNET_HTTP_ITERATION_NUMBER; iteration++) { switch(session->state) { /*---- LISTENING ------------------------------------------------*/ case FNET_HTTP_STATE_LISTENING: len = sizeof(foreign_addr); if((session->socket_foreign = accept(http->socket_listen, &foreign_addr, &len)) != SOCKET_INVALID) { #if FNET_CFG_DEBUG_HTTP { char ip_str[FNET_IP_ADDR_STR_SIZE]; fnet_inet_ntop(foreign_addr.sa_family, (char*)(foreign_addr.sa_data), ip_str, sizeof(ip_str)); FNET_DEBUG_HTTP(""); FNET_DEBUG_HTTP("HTTP: RX Request From: %s; Port: %d.", ip_str, fnet_ntohs(foreign_addr.sa_port)); } #endif /* Reset response & request parameters.*/ fnet_memset_zero(&session->response, sizeof(struct fnet_http_response)); fnet_memset_zero(&session->request, sizeof(struct fnet_http_request)); #if FNET_CFG_HTTP_VERSION_MAJOR /* HTTP/1.x*/ session->response.content_length = -1; /* No content length by default.*/ /* Default HTTP version response.*/ session->response.version.major = FNET_HTTP_VERSION_MAJOR; session->response.version.minor = FNET_HTTP_VERSION_MINOR; session->response.tx_data = fnet_http_tx_status_line; #endif session->state_time = fnet_timer_ticks(); /* Reset timeout. */ session->buffer_actual_size = 0; session->state = FNET_HTTP_STATE_RX_REQUEST; /* => WAITING HTTP REQUEST */ } break; /*---- RX_LINE -----------------------------------------------*/ case FNET_HTTP_STATE_RX_REQUEST: do { /* Read character by character.*/ ch = &session->buffer[session->buffer_actual_size]; if((res = recv(session->socket_foreign, ch, 1, 0) )!= SOCKET_ERROR) { if(res > 0) /* Received a data.*/ { session->state_time = fnet_timer_ticks(); /* Reset timeout.*/ session->buffer_actual_size++; if(*ch == '\r') *ch = '\0'; else if(*ch == '\n') /* Line received.*/ { char * req_buf = &session->buffer[0]; *ch = '\0'; if(session->request.method == 0) /* Parse Request line.*/ { const struct fnet_http_method **method = &fnet_http_method_list[0]; FNET_DEBUG_HTTP("HTTP: RX Request: %s", req_buf); /* Determine the method type. */ while(*method) { if ( !fnet_strcmp_splitter(req_buf, (*method)->token, ' ') ) { req_buf+=fnet_strlen((*method)->token); session->request.method = *method; break; } method++; } /* Check if the method is supported? */ if(session->request.method && session->request.method->handle) { /* Parse URI.*/ req_buf = fnet_http_uri_parse(req_buf, &session->request.uri); FNET_DEBUG_HTTP("HTTP: URI Path = %s; Query = %s", http->request.uri.path, http->request.uri.query); #if FNET_CFG_HTTP_VERSION_MAJOR /* HTTP/1.x*/ /* Parse HTTP/x.x version.*/ fnet_http_version_parse(++req_buf, &session->response.version); /* Check the highest supported HTTP version.*/ if(((session->response.version.major<<8)|session->response.version.minor) > ((FNET_HTTP_VERSION_MAJOR<<8)|FNET_HTTP_VERSION_MINOR)) { session->response.version.major = FNET_HTTP_VERSION_MAJOR; session->response.version.minor = FNET_HTTP_VERSION_MINOR; } if(session->response.version.major == 0) /* HTTP/0.x */ { session->state = FNET_HTTP_STATE_CLOSING; /* Client does not support HTTP/1.x*/ break; } #if FNET_CFG_HTTP_AUTHENTICATION_BASIC /* Check Authentification.*/ fnet_http_auth_validate_uri(http); #endif #endif/*FNET_CFG_HTTP_VERSION_MAJOR*/ /* Call method initial handler.*/ res = session->request.method->handle(http, &session->request.uri); #if FNET_CFG_HTTP_VERSION_MAJOR /* HTTP/1.x*/ if(fnet_http_status_ok(res) == FNET_OK) #else if((res == FNET_OK)) #endif { #if FNET_CFG_HTTP_VERSION_MAJOR /* HTTP/1.x*/ session->buffer_actual_size = 0; /* => Parse Header line.*/ #else /* HTTP/0.9 */ session->response.tx_data = session->request.method->send; /* Reset buffer pointers.*/ session->buffer_actual_size = 0; session->state = FNET_HTTP_STATE_TX; /* Send data.*/ #endif } /* Method error.*/ else /* Error.*/ { #if FNET_CFG_HTTP_VERSION_MAJOR /* HTTP/1.x*/ /* Default code = FNET_HTTP_STATUS_CODE_INTERNAL_SERVER_ERROR. */ if(res != FNET_ERR) session->response.status.code = (fnet_http_status_code_t)res; /* Send status line.*/ session->buffer_actual_size = 0; session->state = FNET_HTTP_STATE_TX; /* Send error.*/ #else /* HTTP/0.9 */ session->state = FNET_HTTP_STATE_CLOSING; #endif } } /* Method is not supported.*/ else /* Error.*/ { #if FNET_CFG_HTTP_VERSION_MAJOR /* HTTP/1.x*/ session->response.status.code = FNET_HTTP_STATUS_CODE_NOT_IMPLEMENTED; /* Send status line.*/ session->buffer_actual_size = 0; session->state = FNET_HTTP_STATE_TX; /* Send error.*/ #else /* HTTP/0.9 */ session->state = FNET_HTTP_STATE_CLOSING; #endif } } #if FNET_CFG_HTTP_VERSION_MAJOR /* HTTP/1.x*/ /* Parse Header line.*/ else { if(session->request.skip_line == 0) { if(*req_buf == 0) /* === Empty line => End of the request header. ===*/ { #if FNET_CFG_HTTP_AUTHENTICATION_BASIC if(session->response.auth_entry) /* Send UNAUTHORIZED error.*/ session->response.status.code = FNET_HTTP_STATUS_CODE_UNAUTHORIZED; else /* Send Data.*/ #endif session->response.status.code = FNET_HTTP_STATUS_CODE_OK; #if FNET_CFG_HTTP_POST if(session->request.content_length > 0) /* RX Entity-Body.*/ { session->buffer_actual_size = 0; session->state = FNET_HTTP_STATE_RX; } else #endif /* TX Full-Responce.*/ { /* Send status line.*/ session->buffer_actual_size = 0; session->state = FNET_HTTP_STATE_TX; } break; } else /* === Parse header fields. ===*/ { FNET_DEBUG_HTTP("HTTP: RX Header: %s", req_buf); #if FNET_CFG_HTTP_AUTHENTICATION_BASIC /* --- Authorization: ---*/ if (session->response.auth_entry && fnet_strncmp(req_buf, FNET_HTTP_HEADER_FIELD_AUTHORIZATION, sizeof(FNET_HTTP_HEADER_FIELD_AUTHORIZATION)-1) == 0) /* Authetication is required.*/ { char *auth_str = &req_buf[sizeof(FNET_HTTP_HEADER_FIELD_AUTHORIZATION)-1]; /* Validate credentials.*/ if(fnet_http_auth_validate_credentials(http, auth_str) == FNET_OK) session->response.auth_entry = 0; /* Authorization is succesful.*/ } #endif #if FNET_CFG_HTTP_POST /* --- Content-Length: ---*/ if (session->request.method->receive && fnet_strncmp(req_buf, FNET_HTTP_HEADER_FIELD_CONTENT_LENGTH, sizeof(FNET_HTTP_HEADER_FIELD_CONTENT_LENGTH)-1) == 0) { char *p; char *length_str = &req_buf[sizeof(FNET_HTTP_HEADER_FIELD_CONTENT_LENGTH)-1]; session->request.content_length = (long)fnet_strtoul(length_str,&p,10); } #endif } } /* Line is skiped.*/ else session->request.skip_line = 0; /* Reset the Skip flag.*/ session->buffer_actual_size = 0; /* => Parse Next Header line.*/ } #endif/* FNET_CFG_HTTP_VERSION_MAJOR */ } /* Not whole line received yet.*/ else if (session->buffer_actual_size == FNET_HTTP_BUF_SIZE) /* Buffer is full.*/ { #if FNET_CFG_HTTP_VERSION_MAJOR /* HTTP/1.x*/ if(session->request.method != 0) /* For header, skip the line.*/ { /* Skip line.*/ session->request.skip_line = 1; session->buffer_actual_size = 0; } else /* Error.*/ { /* Default code = FNET_HTTP_STATUS_CODE_INTERNAL_SERVER_ERROR. */ session->buffer_actual_size = 0; session->state = FNET_HTTP_STATE_TX; /* Send error.*/ } #else /* HTTP/0.9 */ session->state = FNET_HTTP_STATE_CLOSING; #endif } } /* No data.*/ else if(fnet_timer_get_interval(session->state_time, fnet_timer_ticks()) /* Time out? */ > (FNET_HTTP_WAIT_RX_MS / FNET_TIMER_PERIOD_MS)) { session->state = FNET_HTTP_STATE_CLOSING; /*=> CLOSING */ } /* else => WAITING REQUEST. */ } /* recv() error.*/ else { session->state = FNET_HTTP_STATE_CLOSING; /*=> CLOSING */ } } while ((res > 0) && (session->state == FNET_HTTP_STATE_RX_REQUEST)); /* Till receiving the request header.*/ break; #if FNET_CFG_HTTP_POST /*---- RX --------------------------------------------------*/ case FNET_HTTP_STATE_RX: /* Receive data (Entity-Body). */ if((res = recv(session->socket_foreign, &session->buffer[session->buffer_actual_size], (int)(FNET_HTTP_BUF_SIZE-session->buffer_actual_size), 0) )!= SOCKET_ERROR) { session->buffer_actual_size += res; session->request.content_length -= res; if(res > 0) /* Some Data.*/ { session->state_time = fnet_timer_ticks(); /* Reset timeout.*/ res = session->request.method->receive(http); if(fnet_http_status_ok(res) != FNET_OK) { if(res != FNET_ERR) session->response.status.code = (fnet_http_status_code_t)res; else session->response.status.code = FNET_HTTP_STATUS_CODE_INTERNAL_SERVER_ERROR; session->request.content_length = 0; } if(session->request.content_length <= 0) /* The last data.*/ { session->state = FNET_HTTP_STATE_TX; /* Send data.*/ } session->buffer_actual_size = 0; } else /* No Data.*/ { if(fnet_timer_get_interval(session->state_time, fnet_timer_ticks()) > (FNET_HTTP_WAIT_RX_MS / FNET_TIMER_PERIOD_MS)) /* Time out.*/ { session->state = FNET_HTTP_STATE_CLOSING; /*=> CLOSING */ } } } else /* Socket error.*/ { session->state = FNET_HTTP_STATE_CLOSING; /*=> CLOSING */ } break; #endif /* FNET_CFG_HTTP_POST.*/ /*---- TX --------------------------------------------------*/ case FNET_HTTP_STATE_TX: /* Send data. */ if(fnet_timer_get_interval(session->state_time, fnet_timer_ticks()) < (FNET_HTTP_WAIT_TX_MS / FNET_TIMER_PERIOD_MS)) /* Check timeout */ { int send_size; if(session->buffer_actual_size == session->response.buffer_sent) { /* Reset counters.*/ session->buffer_actual_size =0; session->response.buffer_sent = 0; if(session->response.send_eof || session->response.tx_data(http) == FNET_ERR) /* get data for sending */ { session->state = FNET_HTTP_STATE_CLOSING; /*=> CLOSING */ break; } } send_size = (int)(session->buffer_actual_size - (int)session->response.buffer_sent); if(send_size > http->send_max) send_size = (int)http->send_max; if((res = send(session->socket_foreign, session->buffer + session->response.buffer_sent, send_size, 0)) != SOCKET_ERROR) { if(res) { FNET_DEBUG_HTTP("HTTP: TX %d bytes.", res); session->state_time = fnet_timer_ticks(); /* reset timeout */ session->response.buffer_sent += res; } break; /* => SENDING */ } } session->state = FNET_HTTP_STATE_CLOSING; /*=> CLOSING */ break; /*---- CLOSING --------------------------------------------------*/ case FNET_HTTP_STATE_CLOSING: if(session->request.method && session->request.method->close) session->request.method->close(http); closesocket(session->socket_foreign); session->socket_foreign = SOCKET_INVALID; session->state = FNET_HTTP_STATE_LISTENING; /*=> LISTENING */ break; default: break; } } } /*for(sessions)*/ }