Ejemplo n.º 1
0
static int httpd_setup_new_socket(int port)
{
  int one = 1;
  int status, sockfd;
  struct sockaddr_t addr_listen;
  
  /* create listening TCP socket */
  sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (sockfd < 0) {
    status = net_get_sock_error(sockfd);
    httpd_d("Socket creation failed: Port: %d Status: %d", port, status);
    return status;
  }
  
  setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one));

  addr_listen.s_ip = INADDR_ANY;
  addr_listen.s_port = port;
  
  /* bind insocket */
  status = bind(sockfd, &addr_listen, sizeof(addr_listen));
  if (status < 0) {
    status = net_get_sock_error(sockfd);
    httpd_d("Failed to bind socket on port: %d Status: %d", status, port);
    return status;
  }
  
  status = listen(sockfd, HTTPD_MAX_BACKLOG_CONN);
  if (status < 0) {
    status = net_get_sock_error(sockfd);
    httpd_d("Failed to listen on port %d: %d.", port, status);
    return status;
  }
  
  httpd_d("Listening on port %d.", port);
  return sockfd;
}
Ejemplo n.º 2
0
static int httpd_close_sockets()
{
  int ret, status = kNoErr;
  
  if (http_sockfd != -1) {
    ret = close(http_sockfd);
    if (ret != 0) {
      httpd_d("failed to close http socket: %d", net_get_sock_error(http_sockfd));
      status = -kInProgressErr;
    }
  http_sockfd = -1;
  }
  
  if (client_sockfd != -1) {
    ret = close(client_sockfd);
    if (ret != 0) {
      httpd_d("Failed to close client socket: %d", net_get_sock_error(client_sockfd));
      status = -kInProgressErr;
    }
    client_sockfd = -1;
  }
  
  return status;
}
Ejemplo n.º 3
0
/*Helper function to send a buffer over a connection.
 */
int httpd_send(int conn, const char *buf, int len)
{
	int num;
	do {
#ifdef CONFIG_ENABLE_HTTPS
		if (httpd_is_https_active())
			num = tls_send(httpd_tls_handle, buf, len);
		else
#endif /* ENABLE_HTTPS */
			num = send(conn, buf, len, 0);
		if (num < 0) {
			httpd_e("send() failed: %d",
			      net_get_sock_error(conn));
			return -WM_FAIL;
		}
		len -= num;
		buf += len;
	} while (len > 0);


	return WM_SUCCESS;
}
Ejemplo n.º 4
0
static void httpd_handle_client_connection(const fd_set *active_readfds)
{
  int activefds_cnt, status;
  fd_set readfds;
  
  if (httpd_stop_req) {
    httpd_d("HTTPD stop request received");
    httpd_stop_req = FALSE;
    httpd_suspend_thread(false);
  }
  
  status = httpd_accept_client_socket(active_readfds);
  if (status != kNoErr)
    return;
  
  httpd_d("Client socket accepted: %d", client_sockfd);
  FD_ZERO(&readfds);
  FD_SET(client_sockfd, &readfds);
  
  while (1) {
    if (httpd_stop_req) {
      httpd_d("HTTPD stop request received");
      httpd_stop_req = FALSE;
      httpd_suspend_thread(false);
    }
    
    httpd_d("Waiting on client socket");
    activefds_cnt = httpd_select(client_sockfd, &readfds, NULL, HTTPD_CLIENT_SOCK_TIMEOUT);
    
    if (httpd_stop_req) {
      httpd_d("HTTPD stop request received");
      httpd_stop_req = FALSE;
      httpd_suspend_thread(false);
    }
    
    if (activefds_cnt == HTTPD_TIMEOUT_EVENT) {
      /* Timeout has occured */
      httpd_d("Client socket timeout occurred. " "Force closing socket");

      status = close(client_sockfd);
      if (status != kNoErr) {
        status = net_get_sock_error(client_sockfd);
        httpd_d("Failed to close socket %d", status);
        httpd_suspend_thread(true);
      }
      
      client_sockfd = -1;
      break;
    }
    
    httpd_d("Handling %d", client_sockfd);
    /* Note:
    * Connection will be handled with call to
    * httpd_handle_message twice, first for
    * handling request (kNoErr) and second
    * time as there is no more data to receive
    * (client closed connection) and hence
    * will return with status HTTPD_DONE
    * closing socket.
    */
    /* FIXME: remove this memset if all is working well */
    /* memset(&httpd_message_in[0], 0, sizeof(httpd_message_in)); */
    status = httpd_handle_message(client_sockfd);
    if (status == kNoErr) {
      /* The handlers are expected more data on the
      socket */
      continue;
    }
    
    /* Either there was some error or everything went well */
    httpd_d("Close socket %d.  %s: %d", client_sockfd, status == HTTPD_DONE ? "Handler done" : "Handler failed", status);
    
    status = close(client_sockfd);
    if (status != kNoErr) {
      status = net_get_sock_error(client_sockfd);
      httpd_d("Failed to close socket %d", status);
      httpd_suspend_thread(true);
    }
    client_sockfd = -1;
    
    break;
  }
}
Ejemplo n.º 5
0
static int  httpd_accept_client_socket(const fd_set *active_readfds)
{
  int main_sockfd = -1;
  struct sockaddr_t addr_from;
  int addr_from_len;
  
  if (FD_ISSET(http_sockfd, active_readfds)) {
    main_sockfd = http_sockfd;
    https_active  = FALSE;
  }
  
  addr_from_len = sizeof(addr_from);
  
  client_sockfd = accept(main_sockfd, &addr_from, &addr_from_len);
  if (client_sockfd < 0) {
    httpd_d("net_accept client socket failed %d.", client_sockfd);
    return -kInProgressErr;
  }
  
  /*
  * Enable TCP Keep-alive for accepted client connection
  *  -- By enabling this feature TCP sends probe packet if there is
  *  inactivity over connection for specfied interval
  *  -- If there is no response to probe packet for specified retries
  *  then connection is closed with RST packet to peer end
  *  -- Ref: http://tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/
  *
  * We are doing this as we have single threaded web server with
  * synchronous (blocking) API usage like send, recv and they might get
  * blocked due to un-availability of peer end, causing web server to
  * be in-responsive forever.
  */
  int optval = true;
  if (setsockopt(client_sockfd, SOL_SOCKET, 0x0008, &optval, sizeof(optval)) == -1) {
    httpd_d("Unsupported option SO_KEEPALIVE: %d", net_get_sock_error(client_sockfd));
  }
  
  /* TCP Keep-alive idle/inactivity timeout is 10 seconds */
  optval = 10;
  if (setsockopt(client_sockfd, IPPROTO_TCP, 0x03, &optval, sizeof(optval)) == -1) {
    httpd_d("Unsupported option TCP_KEEPIDLE: %d", net_get_sock_error(client_sockfd));
  }
  
  /* TCP Keep-alive retry count is 5 */
  optval = 5;
  if (setsockopt(client_sockfd, IPPROTO_TCP, 0x05, &optval, sizeof(optval)) == -1) {
    httpd_d("Unsupported option TCP_KEEPCNT: %d", net_get_sock_error(client_sockfd));
  }
  
  /* TCP Keep-alive retry interval (in case no response for probe
  * packet) is 1 second.
  */
  optval = 1;
  if (setsockopt(client_sockfd, IPPROTO_TCP, 0x04, &optval, sizeof(optval)) == -1) {
    httpd_d("Unsupported option TCP_KEEPINTVL: %d", net_get_sock_error(client_sockfd));
  }
  
  httpd_d("connecting %d to %d.", client_sockfd, addr_from.s_port);
  
  return kNoErr;
}