Subject: Support to bind accepted socket to device on Linux
[platform/upstream/libwebsockets.git] / lib / context.c
index d35b469..9bf5465 100644 (file)
@@ -150,7 +150,8 @@ lws_protocol_init(struct lws_context *context)
 
                for (n = 0; n < vh->count_protocols; n++) {
                        wsi.protocol = &vh->protocols[n];
-
+                       if (!vh->protocols[n].name)
+                               continue;
                        pvo = lws_vhost_protocol_options(vh,
                                                         vh->protocols[n].name);
                        if (pvo) {
@@ -174,6 +175,13 @@ lws_protocol_init(struct lws_context *context)
                                                   vh->protocols[n].name);
                                                vh->default_protocol_index = n;
                                        }
+                                       if (!strcmp(pvo->name, "raw")) {
+                                               lwsl_notice("Setting raw "
+                                                  "protocol for vh %s to %s\n",
+                                                  vh->name,
+                                                  vh->protocols[n].name);
+                                               vh->raw_protocol_index = n;
+                                       }
                                        pvo = pvo->next;
                                }
 
@@ -233,7 +241,10 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason,
                        if (lws_cgi_write_split_stdout_headers(wsi) < 0)
                                return -1;
 
-                       wsi->reason_bf &= ~1;
+                       if (wsi->reason_bf & 8)
+                               wsi->reason_bf &= ~8;
+                       else
+                               wsi->reason_bf &= ~1;
                        break;
                }
 #endif
@@ -301,12 +312,12 @@ static const struct lws_protocols protocols_dummy[] = {
                lws_callback_http_dummy,                /* callback */
                0,      /* per_session_data_size */
                0,                      /* max frame size / rx buffer */
-               0, NULL
+               0, NULL, 0
        },
        /*
         * the other protocols are provided by lws plugins
         */
-       { NULL, NULL, 0, 0, 0, NULL} /* terminator */
+       { NULL, NULL, 0, 0, 0, NULL, 0} /* terminator */
 };
 
 #ifdef LWS_PLAT_OPTEE
@@ -344,6 +355,10 @@ lws_create_vhost(struct lws_context *context,
                vh->name = info->vhost_name;
 
        vh->iface = info->iface;
+#if !defined(LWS_WITH_ESP8266) && !defined(LWS_WITH_ESP32) && !defined(OPTEE_TA) && !defined(WIN32)
+       vh->bind_iface = info->bind_iface;
+#endif
+
        for (vh->count_protocols = 0;
             info->protocols[vh->count_protocols].callback;
             vh->count_protocols++)
@@ -403,7 +418,11 @@ lws_create_vhost(struct lws_context *context,
        }
 #endif
 
-       if (info->options & LWS_SERVER_OPTION_EXPLICIT_VHOSTS)
+       if (
+#ifdef LWS_WITH_PLUGINS
+           (context->plugin_list) ||
+#endif
+           info->options & LWS_SERVER_OPTION_EXPLICIT_VHOSTS)
                vh->protocols = lwsp;
        else {
                vh->protocols = info->protocols;
@@ -485,9 +504,14 @@ lws_create_vhost(struct lws_context *context,
 #if !defined(LWS_WITH_ESP8266)
        vh->http_proxy_port = 0;
        vh->http_proxy_address[0] = '\0';
+#if defined(LWS_WITH_SOCKS5)
+       vh->socks_proxy_port = 0;
+       vh->socks_proxy_address[0] = '\0';
+#endif
 
        /* either use proxy from info, or try get it from env var */
 
+       /* http proxy */
        if (info->http_proxy_address) {
                /* override for backwards compatibility */
                if (info->http_proxy_port)
@@ -500,7 +524,23 @@ lws_create_vhost(struct lws_context *context,
                        lws_set_proxy(vh, p);
 #endif
        }
+#if defined(LWS_WITH_SOCKS5)
+       /* socks proxy */
+       if (info->socks_proxy_address) {
+               /* override for backwards compatibility */
+               if (info->socks_proxy_port)
+                       vh->socks_proxy_port = info->socks_proxy_port;
+               lws_set_socks(vh, info->socks_proxy_address);
+       } else {
+#ifdef LWS_HAVE_GETENV
+               p = getenv("socks_proxy");
+               if (p)
+                       lws_set_socks(vh, p);
 #endif
+       }
+#endif
+#endif
+
        vh->ka_time = info->ka_time;
        vh->ka_interval = info->ka_interval;
        vh->ka_probes = info->ka_probes;
@@ -571,6 +611,7 @@ LWS_VISIBLE struct lws_context *
 lws_create_context(struct lws_context_creation_info *info)
 {
        struct lws_context *context = NULL;
+       struct lws_plat_file_ops *prev;
 #ifndef LWS_NO_DAEMONIZE
        int pid_daemon = get_daemonize_pid();
 #endif
@@ -603,6 +644,9 @@ lws_create_context(struct lws_context_creation_info *info)
        lwsl_info(" LWS_MAX_SMP           : %u\n", LWS_MAX_SMP);
        lwsl_info(" SPEC_LATEST_SUPPORTED : %u\n", SPEC_LATEST_SUPPORTED);
        lwsl_info(" sizeof (*info)        : %ld\n", (long)sizeof(*info));
+#if defined(LWS_WITH_STATS)
+       lwsl_notice(" LWS_WITH_STATS        : on\n");
+#endif
 #if LWS_POSIX
        lwsl_info(" SYSTEM_RANDOM_FILEPATH: '%s'\n", SYSTEM_RANDOM_FILEPATH);
 #endif
@@ -619,6 +663,37 @@ lws_create_context(struct lws_context_creation_info *info)
        else
                context->pt_serv_buf_size = 4096;
 
+       /* default to just the platform fops implementation */
+
+       context->fops_platform.LWS_FOP_OPEN     = _lws_plat_file_open;
+       context->fops_platform.LWS_FOP_CLOSE    = _lws_plat_file_close;
+       context->fops_platform.LWS_FOP_SEEK_CUR = _lws_plat_file_seek_cur;
+       context->fops_platform.LWS_FOP_READ     = _lws_plat_file_read;
+       context->fops_platform.LWS_FOP_WRITE    = _lws_plat_file_write;
+       context->fops_platform.fi[0].sig        = NULL;
+
+       /*
+        *  arrange a linear linked-list of fops starting from context->fops
+        *
+        * platform fops
+        * [ -> fops_zip (copied into context so .next settable) ]
+        * [ -> info->fops ]
+        */
+
+       context->fops = &context->fops_platform;
+       prev = (struct lws_plat_file_ops *)context->fops;
+
+#if defined(LWS_WITH_ZIP_FOPS)
+       /* make a soft copy so we can set .next */
+       context->fops_zip = fops_zip;
+       prev->next = &context->fops_zip;
+       prev = (struct lws_plat_file_ops *)prev->next;
+#endif
+
+       /* if user provided fops, tack them on the end of the list */
+       if (info->fops)
+               prev->next = info->fops;
+
        context->reject_service_keywords = info->reject_service_keywords;
        if (info->external_baggage_free_on_destroy)
                context->external_baggage_free_on_destroy =
@@ -626,6 +701,8 @@ lws_create_context(struct lws_context_creation_info *info)
 
        context->time_up = time(NULL);
 
+       context->simultaneous_ssl_restriction = info->simultaneous_ssl_restriction;
+
 #ifndef LWS_NO_DAEMONIZE
        if (pid_daemon) {
                context->started_with_parent = pid_daemon;
@@ -743,6 +820,16 @@ lws_create_context(struct lws_context_creation_info *info)
        context->use_ev_sigint = 1;
        context->lws_uv_sigint_cb = &lws_uv_sigint_cb;
 #endif
+#ifdef LWS_USE_LIBEVENT
+       /* (Issue #264) In order to *avoid breaking backwards compatibility*, we
+        * enable libev mediated SIGINT handling with a default handler of
+        * lws_sigint_cb. The handler can be overridden or disabled
+        * by invoking lws_sigint_cfg after creating the context, but
+        * before invoking lws_initloop:
+        */
+       context->use_ev_sigint = 1;
+       context->lws_event_sigint_cb = &lws_event_sigint_cb;
+#endif /* LWS_USE_LIBEVENT */
 
        lwsl_info(" mem: context:         %5lu bytes (%ld ctx + (%ld thr x %d))\n",
                  (long)sizeof(struct lws_context) +
@@ -772,9 +859,6 @@ lws_create_context(struct lws_context_creation_info *info)
                context->server_string = info->server_string;
                context->server_string_len = (short)
                                strlen(context->server_string);
-       } else {
-               context->server_string = "libwebsockets";
-               context->server_string_len = 13;
        }
 
 #if LWS_MAX_SMP > 1
@@ -812,6 +896,11 @@ lws_create_context(struct lws_context_creation_info *info)
        context->uid = info->uid;
        context->gid = info->gid;
 
+#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
+       memcpy(context->caps, info->caps, sizeof(context->caps));
+       context->count_caps = info->count_caps;
+#endif
+
        /*
         * drop any root privs for this process
         * to listen on port < 1023 we would have needed root, but now we are
@@ -979,6 +1068,7 @@ lws_context_destroy(struct lws_context *context)
 
                lws_libev_destroyloop(context, n);
                lws_libuv_destroyloop(context, n);
+               lws_libevent_destroyloop(context, n);
 
                lws_free_set_NULL(context->pt[n].serv_buf);
                if (pt->ah_pool)
@@ -1055,12 +1145,13 @@ lws_context_destroy2(struct lws_context *context)
                vh = vh1;
        }
 
+       lws_stats_log_dump(context);
+
        lws_ssl_context_destroy(context);
        lws_plat_context_late_destroy(context);
 
        if (context->external_baggage_free_on_destroy)
                free(context->external_baggage_free_on_destroy);
 
-
        lws_free(context);
 }