int insert_wsi_socket_into_fds(struct lws_context *context, struct lws *wsi) { struct lws_pollargs pa = { wsi->sock, LWS_POLLIN, 0 }; struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; int ret = 0; #ifndef LWS_NO_SERVER struct lws_pollargs pa1; #endif lwsl_debug("%s: %p: tsi=%d, sock=%d, pos-in-fds=%d\n", __func__, wsi, wsi->tsi, wsi->sock, pt->fds_count); if ((unsigned int)pt->fds_count >= context->fd_limit_per_thread) { lwsl_err("Too many fds (%d)\n", context->max_fds); return 1; } #if !defined(_WIN32) && !defined(MBED_OPERATORS) if (wsi->sock >= context->max_fds) { lwsl_err("Socket fd %d is too high (%d)\n", wsi->sock, context->max_fds); return 1; } #endif assert(wsi); assert(lws_socket_is_valid(wsi->sock)); if (context->protocols[0].callback(wsi, LWS_CALLBACK_LOCK_POLL, wsi->user_space, (void *) &pa, 1)) return -1; lws_pt_lock(pt); pt->count_conns++; insert_wsi(context, wsi); wsi->position_in_fds_table = pt->fds_count; pt->fds[pt->fds_count].fd = wsi->sock; pt->fds[pt->fds_count].events = LWS_POLLIN; pa.events = pt->fds[pt->fds_count].events; lws_plat_insert_socket_into_fds(context, wsi); /* external POLL support via protocol 0 */ if (context->protocols[0].callback(wsi, LWS_CALLBACK_ADD_POLL_FD, wsi->user_space, (void *) &pa, 0)) ret = -1; #ifndef LWS_NO_SERVER /* if no more room, defeat accepts on this thread */ if ((unsigned int)pt->fds_count == context->fd_limit_per_thread - 1) _lws_change_pollfd(pt->wsi_listening, LWS_POLLIN, 0, &pa1); #endif lws_pt_unlock(pt); if (context->protocols[0].callback(wsi, LWS_CALLBACK_UNLOCK_POLL, wsi->user_space, (void *)&pa, 1)) ret = -1; return ret; }
int insert_wsi_socket_into_fds(struct libwebsocket_context *context, struct libwebsocket *wsi) { struct libwebsocket_pollargs pa = { wsi->sock, LWS_POLLIN, 0 }; if (context->fds_count >= context->max_fds) { lwsl_err("Too many fds (%d)\n", context->max_fds); return 1; } #if !defined(_WIN32) && !defined(MBED_OPERATORS) if (wsi->sock >= context->max_fds) { lwsl_err("Socket fd %d is too high (%d)\n", wsi->sock, context->max_fds); return 1; } #endif assert(wsi); assert(lws_socket_is_valid(wsi->sock)); // lwsl_info("insert_wsi_socket_into_fds: wsi=%p, sock=%d, fds pos=%d\n", // wsi, wsi->sock, context->fds_count); if (context->protocols[0].callback(context, wsi, LWS_CALLBACK_LOCK_POLL, wsi->user_space, (void *) &pa, 0)) return -1; insert_wsi(context, wsi); wsi->position_in_fds_table = context->fds_count; context->fds[context->fds_count].fd = wsi->sock; context->fds[context->fds_count].events = LWS_POLLIN; lws_plat_insert_socket_into_fds(context, wsi); /* external POLL support via protocol 0 */ if (context->protocols[0].callback(context, wsi, LWS_CALLBACK_ADD_POLL_FD, wsi->user_space, (void *) &pa, 0)) return -1; if (context->protocols[0].callback(context, wsi, LWS_CALLBACK_UNLOCK_POLL, wsi->user_space, (void *)&pa, 0)) return -1; return 0; }
int insert_wsi_socket_into_fds(struct lws_context *context, struct lws *wsi) { struct lws_pollargs pa = { wsi->sock, LWS_POLLIN, 0 }; struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; if ((unsigned int)pt->fds_count >= context->fd_limit_per_thread) { lwsl_err("Too many fds (%d)\n", context->max_fds); return 1; } #if !defined(_WIN32) && !defined(MBED_OPERATORS) if (wsi->sock >= context->max_fds) { lwsl_err("Socket fd %d is too high (%d)\n", wsi->sock, context->max_fds); return 1; } #endif assert(wsi); assert(lws_socket_is_valid(wsi->sock)); if (context->protocols[0].callback(wsi, LWS_CALLBACK_LOCK_POLL, wsi->user_space, (void *) &pa, 1)) return -1; insert_wsi(context, wsi); wsi->position_in_fds_table = pt->fds_count; pt->fds[pt->fds_count].fd = wsi->sock; pt->fds[pt->fds_count].events = LWS_POLLIN; lws_plat_insert_socket_into_fds(context, wsi); /* external POLL support via protocol 0 */ if (context->protocols[0].callback(wsi, LWS_CALLBACK_ADD_POLL_FD, wsi->user_space, (void *) &pa, 0)) return -1; if (context->protocols[0].callback(wsi, LWS_CALLBACK_UNLOCK_POLL, wsi->user_space, (void *)&pa, 1)) return -1; return 0; }
struct libwebsocket * __libwebsocket_client_connect_2( struct libwebsocket_context *context, struct libwebsocket *wsi ) { struct pollfd pfd; struct timeval tv; struct hostent *server_hostent; struct sockaddr_in server_addr; int n; int plen = 0; char pkt[512]; int opt = 1; #if defined(__APPLE__) struct protoent* tcp_proto; #endif lws_log(LWS_LOG_DEBUG, "__libwebsocket_client_connect_2"); wsi->candidate_children_list = NULL; /* * proxy? */ if (context->http_proxy_port) { plen = sprintf(pkt, "CONNECT %s:%u HTTP/1.0\x0d\x0a" "User-agent: libwebsockets\x0d\x0a" /*Proxy-authorization: basic aGVsbG86d29ybGQ= */ "\x0d\x0a", wsi->c_address, wsi->c_port); /* OK from now on we talk via the proxy */ free(wsi->c_address); wsi->c_address = strdup(context->http_proxy_address); wsi->c_port = context->http_proxy_port; } /* * prepare the actual connection (to the proxy, if any) */ lws_log(LWS_LOG_DEBUG, "__libwebsocket_client_connect_2: address %s", wsi->c_address); server_hostent = gethostbyname(wsi->c_address); if (server_hostent == NULL) { lws_log(LWS_LOG_WARNING, "Unable to get host name from %s", wsi->c_address); goto oom4; } wsi->sock = socket(AF_INET, SOCK_STREAM, 0); if (wsi->sock < 0) { lws_log(LWS_LOG_WARNING, "Unable to open socket"); goto oom4; } server_addr.sin_family = AF_INET; server_addr.sin_port = htons(wsi->c_port); server_addr.sin_addr = *((struct in_addr *)server_hostent->h_addr); bzero(&server_addr.sin_zero, 8); /* Disable Nagle */ #if !defined(__APPLE__) setsockopt(wsi->sock, SOL_TCP, TCP_NODELAY, (const void *)&opt, sizeof(opt)); #else tcp_proto = getprotobyname("TCP"); setsockopt(wsi->sock, tcp_proto->p_proto, TCP_NODELAY, &opt, sizeof(opt)); #endif /* Set receiving timeout */ tv.tv_sec = 0; tv.tv_usec = 100 * 1000; setsockopt(wsi->sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof tv); /* Set sendind timeout */ tv.tv_sec = 0; tv.tv_usec = 100 * 1000; setsockopt(wsi->sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof tv); if (connect(wsi->sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) { lws_log(LWS_LOG_WARNING, "Connect failed"); #ifdef WIN32 closesocket(wsi->sock); #else close(wsi->sock); #endif goto oom4; } lws_log(LWS_LOG_DEBUG, "connected"); /* into fd -> wsi hashtable */ insert_wsi(context, wsi); /* into internal poll list */ context->fds[context->fds_count].fd = wsi->sock; context->fds[context->fds_count].revents = 0; context->fds[context->fds_count++].events = POLLIN; /* external POLL support via protocol 0 */ context->protocols[0].callback(context, wsi, LWS_CALLBACK_ADD_POLL_FD, (void *)(long)wsi->sock, NULL, POLLIN); /* we are connected to server, or proxy */ if (context->http_proxy_port) { n = send(wsi->sock, pkt, plen, 0); if (n < 0) { #ifdef WIN32 closesocket(wsi->sock); #else close(wsi->sock); #endif lws_log(LWS_LOG_ERROR, "ERROR writing to proxy socket"); goto bail1; } libwebsocket_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE, AWAITING_TIMEOUT); wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_PROXY_REPLY; return wsi; } /* * provoke service to issue the handshake directly * we need to do it this way because in the proxy case, this is the * next state and executed only if and when we get a good proxy * response inside the state machine */ wsi->mode = LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE; pfd.fd = wsi->sock; pfd.revents = POLLIN; if (libwebsocket_service_fd(context, &pfd)) /* returns 1 on failure after closing wsi */ { return NULL; } return wsi; oom4: if (wsi->c_protocol) free(wsi->c_protocol); if (wsi->c_origin) free(wsi->c_origin); free(wsi->c_host); free(wsi->c_path); bail1: free(wsi); return NULL; }