diff --git a/lib/core-net/client/connect2.c b/lib/core-net/client/connect2.c index b207ad800..9e1bbe5d4 100644 --- a/lib/core-net/client/connect2.c +++ b/lib/core-net/client/connect2.c @@ -311,7 +311,7 @@ solo: lwsi_set_state(wsi, LRS_WAITING_DNS); lwsl_info("%s: %s: lookup %s:%u\n", __func__, wsi->lc.gutag, ads, port); - (void)port; + wsi->conn_port = (uint16_t)port; #if defined(LWS_WITH_DETAILED_LATENCY) wsi->detlat.earliest_write_req_pre_write = lws_now_usecs(); diff --git a/lib/core-net/client/connect3.c b/lib/core-net/client/connect3.c index e687e143b..5418cfd5d 100644 --- a/lib/core-net/client/connect3.c +++ b/lib/core-net/client/connect3.c @@ -129,7 +129,7 @@ lws_client_connect_3_connect(struct lws *wsi, const char *ads, #endif struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi]; const struct sockaddr *psa = NULL; - uint16_t port = wsi->c_port; + uint16_t port = wsi->conn_port; const char *cce, *iface; lws_dns_sort_t *curr; ssize_t plen = 0; diff --git a/lib/core-net/client/connect4.c b/lib/core-net/client/connect4.c index b3e503df3..eaa05e2cc 100644 --- a/lib/core-net/client/connect4.c +++ b/lib/core-net/client/connect4.c @@ -106,6 +106,7 @@ lws_client_connect_4_established(struct lws *wsi, struct lws *wsi_piggyback, lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE, (int)wsi->a.context->timeout_secs); + wsi->conn_port = wsi->c_port; lwsi_set_state(wsi, LRS_WAITING_PROXY_REPLY); return wsi; diff --git a/lib/core-net/client/sort-dns.c b/lib/core-net/client/sort-dns.c index 406e9f317..d40b72645 100644 --- a/lib/core-net/client/sort-dns.c +++ b/lib/core-net/client/sort-dns.c @@ -562,7 +562,7 @@ lws_sort_dns_dump(struct lws *wsi) (void)n; /* nologs */ if (!lws_dll2_get_head(&wsi->dns_sorted_list)) - lwsl_info("%s: empty\n", __func__); + lwsl_notice("%s: empty\n", __func__); lws_start_foreach_dll(struct lws_dll2 *, d, lws_dll2_get_head(&wsi->dns_sorted_list)) { @@ -572,7 +572,7 @@ lws_sort_dns_dump(struct lws *wsi) lws_sa46_write_numeric_address(&s->dest, dest, sizeof(dest)); lws_sa46_write_numeric_address(&s->gateway, gw, sizeof(gw)); - lwsl_info("%s: %d: (%d)%s, gw (%d)%s, idi: %d, " + lwsl_notice("%s: %d: (%d)%s, gw (%d)%s, idi: %d, " "lbl: %d, prec: %d\n", __func__, n++, s->dest.sa4.sin_family, dest, s->gateway.sa4.sin_family, gw, @@ -648,12 +648,13 @@ lws_sort_dns(struct lws *wsi, const struct addrinfo *result) * we don't have a way to use it if we listed it */ - if (pt->routing_table.count) { + if (pt->context->routing_table.count) { estr = _lws_route_est_outgoing(pt, &ds->dest); if (!estr) { lws_free(ds); - lwsl_info("%s: no route out\n", __func__); + lwsl_notice("%s: %s has no route out\n", + __func__, afip); /* * There's no outbound route for this, it's * unusable, so don't add it to the list @@ -716,7 +717,7 @@ lws_sort_dns(struct lws *wsi, const struct addrinfo *result) */ lws_start_foreach_dll(struct lws_dll2 *, d, - lws_dll2_get_head(&pt->routing_table)) { + lws_dll2_get_head(&pt->context->routing_table)) { lws_route_t *r = lws_container_of(d, lws_route_t, list); /* gateway routes are skipped here */ @@ -731,7 +732,7 @@ lws_sort_dns(struct lws *wsi, const struct addrinfo *result) /* bestsrc is the best source route, or NULL if none */ - if (!bestsrc && pt->routing_table.count) { + if (!bestsrc && pt->context->routing_table.count) { /* drop it, no usable source route */ lws_free(ds); goto next; diff --git a/lib/core-net/network.c b/lib/core-net/network.c index 1609e169d..72d5db99f 100644 --- a/lib/core-net/network.c +++ b/lib/core-net/network.c @@ -881,7 +881,18 @@ lws_sa46_write_numeric_address(lws_sockaddr46 *sa46, char *buf, size_t len) return lws_write_numeric_address( (uint8_t *)&sa46->sa4.sin_addr, 4, buf, len); - lws_snprintf(buf, len, "(bad AF %d)", (int)sa46->sa4.sin_family); +#if defined(LWS_WITH_UNIX_SOCK) + if (sa46->sa4.sin_family == AF_UNIX) + return lws_snprintf(buf, len, "(unix skt)"); +#endif + + if (!sa46->sa4.sin_family) + return lws_snprintf(buf, len, "(unset)"); + + if (sa46->sa4.sin_family == AF_INET6) + lws_snprintf(buf, len, "(ipv6 unsupp)"); + + lws_snprintf(buf, len, "(AF%d unsupp)", (int)sa46->sa4.sin_family); return -1; } diff --git a/lib/core-net/pollfd.c b/lib/core-net/pollfd.c index 20868820e..f3ecb61cf 100644 --- a/lib/core-net/pollfd.c +++ b/lib/core-net/pollfd.c @@ -298,7 +298,7 @@ __insert_wsi_socket_into_fds(struct lws_context *context, struct lws *wsi) assert(wsi); #if defined(LWS_WITH_NETLINK) - assert(wsi->event_pipe || wsi->a.vhost || wsi == pt->netlink); + assert(wsi->event_pipe || wsi->a.vhost || wsi == pt->context->netlink); #else assert(wsi->event_pipe || wsi->a.vhost); #endif diff --git a/lib/core-net/private-lib-core-net.h b/lib/core-net/private-lib-core-net.h index b7356d4b6..a489fc45d 100644 --- a/lib/core-net/private-lib-core-net.h +++ b/lib/core-net/private-lib-core-net.h @@ -402,11 +402,6 @@ struct lws_context_per_thread { lws_sockfd_type dummy_pipe_fds[2]; struct lws *pipe_wsi; -#if defined(LWS_WITH_NETLINK) - lws_dll2_owner_t routing_table; - struct lws *netlink; -#endif - /* --- role based members --- */ #if defined(LWS_ROLE_WS) && !defined(LWS_WITHOUT_EXTENSIONS) @@ -450,10 +445,6 @@ struct lws_context_per_thread { unsigned char tid; -#if defined(LWS_WITH_NETLINK) - lws_route_uidx_t route_uidx; -#endif - unsigned char inside_service:1; unsigned char inside_lws_service:1; unsigned char event_loop_foreign:1; @@ -889,7 +880,7 @@ struct lws { unsigned int sock_send_blocking:1; #endif - uint16_t ocport, c_port; + uint16_t ocport, c_port, conn_port; uint16_t retry; #if defined(LWS_WITH_CLIENT) uint16_t keep_warm_secs; @@ -1411,7 +1402,7 @@ void _lws_routing_entry_dump(lws_route_t *rou); void -_lws_routing_table_dump(struct lws_context_per_thread *pt); +_lws_routing_table_dump(struct lws_context *cx); #define LRR_IGNORE_PRI (1 << 0) #define LRR_MATCH_SRC (1 << 1) @@ -1426,7 +1417,7 @@ void _lws_route_table_ifdown(struct lws_context_per_thread *pt, int idx); lws_route_uidx_t -_lws_route_get_uidx(struct lws_context_per_thread *pt); +_lws_route_get_uidx(struct lws_context *cx); int _lws_route_pt_close_route_users(struct lws_context_per_thread *pt, diff --git a/lib/core-net/route.c b/lib/core-net/route.c index 58419aa7d..d5c56feff 100644 --- a/lib/core-net/route.c +++ b/lib/core-net/route.c @@ -31,28 +31,43 @@ #include #if defined(_DEBUG) + + + void _lws_routing_entry_dump(lws_route_t *rou) { - char sa[48], da[48], gw[48]; + char sa[48], fin[192], *end = &fin[sizeof(fin)]; + int n = 0; - lws_sa46_write_numeric_address(&rou->src, sa, sizeof(sa)); - lws_sa46_write_numeric_address(&rou->dest, da, sizeof(da)); - lws_sa46_write_numeric_address(&rou->gateway, gw, sizeof(gw)); + if (rou->dest.sa4.sin_family) { + lws_sa46_write_numeric_address(&rou->dest, sa, sizeof(sa)); + n += lws_snprintf(fin, lws_ptr_diff_size_t(end, fin), + "dst: %s/%d, ", sa, rou->dest_len); + } - lwsl_info(" dst: (%d)%s/%d, src: (%d)%s/%d, gw: (%d)%s, ifidx: %d, pri: %d, proto: %d\n", - rou->dest.sa4.sin_family, da, rou->dest_len, - rou->src.sa4.sin_family, sa, rou->src_len, - rou->gateway.sa4.sin_family, gw, - rou->if_idx, rou->priority, rou->proto); + if (rou->src.sa4.sin_family) { + lws_sa46_write_numeric_address(&rou->src, sa, sizeof(sa)); + n += lws_snprintf(fin, lws_ptr_diff_size_t(end, fin), + "src: %s/%d, ", sa, rou->src_len); + } + + if (rou->gateway.sa4.sin_family) { + lws_sa46_write_numeric_address(&rou->gateway, sa, sizeof(sa)); + n += lws_snprintf(fin, lws_ptr_diff_size_t(end, fin), + "gw: %s, ", sa); + } + + lwsl_info(" %s ifidx: %d, pri: %d, proto: %d\n", fin, + rou->if_idx, rou->priority, rou->proto); } void -_lws_routing_table_dump(struct lws_context_per_thread *pt) +_lws_routing_table_dump(struct lws_context *cx) { lwsl_info("%s\n", __func__); lws_start_foreach_dll(struct lws_dll2 *, d, - lws_dll2_get_head(&pt->routing_table)) { + lws_dll2_get_head(&cx->routing_table)) { lws_route_t *rou = lws_container_of(d, lws_route_t, list); _lws_routing_entry_dump(rou); @@ -80,10 +95,10 @@ _lws_routing_table_dump(struct lws_context_per_thread *pt) */ lws_route_uidx_t -_lws_route_get_uidx(struct lws_context_per_thread *pt) +_lws_route_get_uidx(struct lws_context *cx) { - if (!pt->route_uidx) - pt->route_uidx++; + if (!cx->route_uidx) + cx->route_uidx++; while (1) { char again = 0; @@ -91,20 +106,20 @@ _lws_route_get_uidx(struct lws_context_per_thread *pt) /* Anybody in the table already uses the pt's next uidx? */ lws_start_foreach_dll(struct lws_dll2 *, d, - lws_dll2_get_head(&pt->routing_table)) { + lws_dll2_get_head(&cx->routing_table)) { lws_route_t *rou = lws_container_of(d, lws_route_t, list); - if (rou->uidx == pt->route_uidx) { + if (rou->uidx == cx->route_uidx) { /* if so, bump and restart the check */ - pt->route_uidx++; - if (!pt->route_uidx) - pt->route_uidx++; + cx->route_uidx++; + if (!cx->route_uidx) + cx->route_uidx++; again = 1; } } lws_end_foreach_dll(d); if (!again) - return pt->route_uidx++; + return cx->route_uidx++; } } @@ -112,7 +127,7 @@ int _lws_route_remove(struct lws_context_per_thread *pt, lws_route_t *robj, int flags) { lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1, - lws_dll2_get_head(&pt->routing_table)) { + lws_dll2_get_head(&pt->context->routing_table)) { lws_route_t *rou = lws_container_of(d, lws_route_t, list); if ((!(flags & LRR_MATCH_SRC) || !lws_sa46_compare_ads(&robj->src, &rou->src)) && @@ -139,7 +154,7 @@ void _lws_route_table_empty(struct lws_context_per_thread *pt) { lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1, - lws_dll2_get_head(&pt->routing_table)) { + lws_dll2_get_head(&pt->context->routing_table)) { lws_route_t *rou = lws_container_of(d, lws_route_t, list); lws_dll2_remove(&rou->list); lws_free(rou); @@ -151,7 +166,7 @@ void _lws_route_table_ifdown(struct lws_context_per_thread *pt, int idx) { lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1, - lws_dll2_get_head(&pt->routing_table)) { + lws_dll2_get_head(&pt->context->routing_table)) { lws_route_t *rou = lws_container_of(d, lws_route_t, list); if (rou->if_idx == idx) { @@ -183,7 +198,7 @@ _lws_route_est_outgoing(struct lws_context_per_thread *pt, */ lws_start_foreach_dll(struct lws_dll2 *, d, - lws_dll2_get_head(&pt->routing_table)) { + lws_dll2_get_head(&pt->context->routing_table)) { lws_route_t *rou = lws_container_of(d, lws_route_t, list); // _lws_routing_entry_dump(rou); @@ -242,7 +257,7 @@ _lws_route_find_source(struct lws_context_per_thread *pt, const lws_sockaddr46 *src) { lws_start_foreach_dll(struct lws_dll2 *, d, - lws_dll2_get_head(&pt->routing_table)) { + lws_dll2_get_head(&pt->context->routing_table)) { lws_route_t *rou = lws_container_of(d, lws_route_t, list); // _lws_routing_entry_dump(rou); @@ -318,7 +333,7 @@ _lws_route_pt_close_unroutable(struct lws_context_per_thread *pt) lwsl_debug("%s\n", __func__); #if defined(_DEBUG) - _lws_routing_table_dump(pt); + _lws_routing_table_dump(pt->context); #endif for (n = 0; n < pt->fds_count; n++) { diff --git a/lib/core/private-lib-core.h b/lib/core/private-lib-core.h index 4ac1a46f5..47ad0b5e1 100644 --- a/lib/core/private-lib-core.h +++ b/lib/core/private-lib-core.h @@ -405,6 +405,9 @@ struct lws_context { #if defined(LWS_WITH_NETLINK) lws_sorted_usec_list_t sul_nl_coldplug; + /* process can only have one netlink socket, have to do it in ctx */ + lws_dll2_owner_t routing_table; + struct lws *netlink; #endif #if defined(LWS_PLAT_FREERTOS) || defined(WIN32) @@ -625,6 +628,10 @@ struct lws_context { uint16_t smd_queue_depth; #endif +#if defined(LWS_WITH_NETLINK) + lws_route_uidx_t route_uidx; +#endif + unsigned int deprecated:1; unsigned int inside_context_destroy:1; unsigned int being_destroyed:1; diff --git a/lib/roles/netlink/ops-netlink.c b/lib/roles/netlink/ops-netlink.c index 77ae2c4bb..519a40357 100644 --- a/lib/roles/netlink/ops-netlink.c +++ b/lib/roles/netlink/ops-netlink.c @@ -41,7 +41,7 @@ #define RTA_ALIGNTO 4U //#define lwsl_netlink lwsl_notice -#define lwsl_netlink lwsl_debug +#define lwsl_netlink lwsl_info static void lws_netlink_coldplug_done_cb(lws_sorted_usec_list_t *sul) @@ -58,6 +58,7 @@ static int rops_handle_POLLIN_netlink(struct lws_context_per_thread *pt, struct lws *wsi, struct lws_pollfd *pollfd) { + struct lws_context *cx = pt->context; uint8_t s[4096] #if defined(_DEBUG) , route_change = 0 @@ -77,16 +78,16 @@ rops_handle_POLLIN_netlink(struct lws_context_per_thread *pt, struct lws *wsi, if (!(pollfd->revents & LWS_POLLIN)) return LWS_HPI_RET_HANDLED; - if (!pt->context->nl_initial_done && pt == &pt->context->pt[0]) { + if (!cx->nl_initial_done && pt == &cx->pt[0]) { /* * While netlink info still coming, keep moving the timer for * calling it "done" to +100ms until after it stops coming */ - lws_context_lock(pt->context, __func__); - lws_sul_schedule(pt->context, 0, &pt->context->sul_nl_coldplug, + lws_context_lock(cx, __func__); + lws_sul_schedule(cx, 0, &cx->sul_nl_coldplug, lws_netlink_coldplug_done_cb, 100 * LWS_US_PER_MS); - lws_context_unlock(pt->context); + lws_context_unlock(cx); } memset(&msg, 0, sizeof(msg)); @@ -388,8 +389,8 @@ ana: * cannot race */ - rou->uidx = _lws_route_get_uidx(pt); - lws_dll2_add_tail(&rou->list, &pt->routing_table); + rou->uidx = _lws_route_get_uidx(cx); + lws_dll2_add_tail(&rou->list, &cx->routing_table); _lws_route_pt_close_unroutable(pt); @@ -405,7 +406,7 @@ inform: * Participants interested can refer to the pt * routing table */ - (void)lws_smd_msg_printf(pt->context, LWSSMDCL_NETWORK, + (void)lws_smd_msg_printf(cx, LWSSMDCL_NETWORK, "{\"rt\":\"%s\"}\n", (h->nlmsg_type == RTM_DELROUTE) ? "del" : "add"); @@ -426,16 +427,16 @@ inform: * If a route with a gw was added or deleted, retrigger captive * portal detection if we have that */ - (void)lws_smd_msg_printf(pt->context, LWSSMDCL_NETWORK, + (void)lws_smd_msg_printf(cx, LWSSMDCL_NETWORK, "{\"trigger\": \"cpdcheck\", " "\"src\":\"gw-change\"}"); #endif #if defined(_DEBUG) if (route_change) { - lws_pt_lock(pt, __func__); - _lws_routing_table_dump(pt); - lws_pt_unlock(pt); + lws_context_lock(cx, __func__); + _lws_routing_table_dump(cx); + lws_context_unlock(cx); } #endif @@ -470,7 +471,7 @@ rops_pt_init_destroy_netlink(struct lws_context *context, return 0; } - if (pt->netlink) + if (context->netlink) return 0; if (pt > &context->pt[0]) @@ -515,7 +516,7 @@ rops_pt_init_destroy_netlink(struct lws_context *context, goto bail2; } - pt->netlink = wsi; + context->netlink = wsi; if (lws_wsi_inject_to_loop(pt, wsi)) goto bail2;