@@ -479,8 +479,10 @@ monitor_req_cb(struct lejp_ctx *ctx, char reason)
479479 }
480480
481481 if (reason == LEJPCB_VAL_NUM_INT ) {
482- if (ctx -> path_match - 1 == LRP_PORT )
482+ if (ctx -> path_match - 1 == LRP_PORT ) {
483483 a -> port = atoi (ctx -> buf );
484+ lwsl_notice ("[INSTRUMENT] monitor_req_cb: Parsed port natively from JSON INT: %d\n" , a -> port );
485+ }
484486 }
485487
486488 if (reason == LEJPCB_VAL_STR_CHUNK || reason == LEJPCB_VAL_STR_END ) {
@@ -550,6 +552,10 @@ handle_req_status(struct vhd *vhd, struct pss *root_pss, struct monitor_req_args
550552 root_pss -> tx_len = lws_ptr_diff_size_t (tx , (char * )& root_pss -> tx [LWS_PRE ]);
551553}
552554
555+ static int cmp_str (const void * a , const void * b ) {
556+ return strcmp (* (const char * * )a , * (const char * * )b );
557+ }
558+
553559static void
554560handle_req_get_domains (struct vhd * vhd , struct pss * root_pss , struct monitor_req_args * a )
555561{
@@ -564,17 +570,34 @@ handle_req_get_domains(struct vhd *vhd, struct pss *root_pss, struct monitor_req
564570 if (!d ) {
565571 tx += lws_snprintf (tx , lws_ptr_diff_size_t (tx_end , tx ), "{\"req\":\"get_domains\",\"status\":\"error\",\"msg\":\"Cannot open base_dir\"}\n" );
566572 } else {
567- int first = 1 ;
568- tx += lws_snprintf (tx , lws_ptr_diff_size_t (tx_end , tx ), "{\"req\":\"get_domains\",\"status\":\"ok\",\"domains\":[" );
573+ char * * doms = NULL ;
574+ size_t count = 0 , alloc = 0 ;
575+
569576 while ((de = readdir (d ))) {
570577 if (de -> d_name [0 ] == '.' ) continue ;
571578 if (de -> d_type == DT_DIR || de -> d_type == DT_UNKNOWN ) {
572- if (!first ) tx += lws_snprintf (tx , lws_ptr_diff_size_t (tx_end , tx ), "," );
573- tx += lws_snprintf (tx , lws_ptr_diff_size_t (tx_end , tx ), "\"%s\"" , de -> d_name );
574- first = 0 ;
579+ if (count >= alloc ) {
580+ alloc = alloc ? alloc * 2 : 16 ;
581+ char * * ndoms = realloc (doms , alloc * sizeof (char * ));
582+ if (!ndoms ) break ;
583+ doms = ndoms ;
584+ }
585+ doms [count ++ ] = strdup (de -> d_name );
575586 }
576587 }
577588 closedir (d );
589+
590+ if (count ) {
591+ qsort (doms , count , sizeof (char * ), cmp_str );
592+ }
593+
594+ tx += lws_snprintf (tx , lws_ptr_diff_size_t (tx_end , tx ), "{\"req\":\"get_domains\",\"status\":\"ok\",\"domains\":[" );
595+ for (size_t i = 0 ; i < count ; i ++ ) {
596+ if (i > 0 ) tx += lws_snprintf (tx , lws_ptr_diff_size_t (tx_end , tx ), "," );
597+ tx += lws_snprintf (tx , lws_ptr_diff_size_t (tx_end , tx ), "\"%s\"" , doms [i ]);
598+ free (doms [i ]);
599+ }
600+ if (doms ) free (doms );
578601 tx += lws_snprintf (tx , lws_ptr_diff_size_t (tx_end , tx ), "]}\n" );
579602 }
580603 root_pss -> tx_len = lws_ptr_diff_size_t (tx , (char * )& root_pss -> tx [LWS_PRE ]);
@@ -906,14 +929,14 @@ handle_req_check_cert(struct vhd *vhd, struct pss *root_pss, struct monitor_req_
906929 memset (& i , 0 , sizeof (i ));
907930 i .context = vhd -> context ;
908931
909- struct lws_vhost * vh = lws_get_vhost_by_name (vhd -> context , "dnssec_monitor_uds " );
932+ struct lws_vhost * vh = lws_get_vhost_by_name (vhd -> context , "root-monitor-dummy " );
910933 i .vhost = vh ? vh : vhd -> vhost ;
911934
912935 i .address = a -> subdomain ;
913936 i .port = a -> port ;
914937 i .ssl_connection = LCCSCF_USE_SSL | LCCSCF_ALLOW_SELFSIGNED | LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK ;
915938 i .alpn = "http/1.1" ;
916- i .method = "GET " ;
939+ i .method = "RAW " ;
917940 i .path = "/" ;
918941 i .host = i .address ;
919942 i .origin = i .address ;
@@ -1016,7 +1039,6 @@ static const struct monitor_req_map {
10161039 { "save_auth_key" , handle_req_save_auth_key },
10171040 { "save_cert" , handle_req_save_cert },
10181041 { "save_key" , handle_req_save_key },
1019- { "check_cert" , handle_req_check_cert },
10201042 { "get_ipv6_suffix" , handle_req_get_ipv6_suffix },
10211043 { "set_ipv6_suffix" , handle_req_set_ipv6_suffix }
10221044};
@@ -1569,6 +1591,22 @@ callback_dht_dnssec_monitor(struct lws *wsi, enum lws_callback_reasons reason,
15691591 case LWS_CALLBACK_RECEIVE :
15701592 lwsl_debug ("[INSTRUMENT] LWS_CALLBACK_RECEIVE: Browser UI triggered WS message (len: %d). Proxy cwsi=%p, root_process_active=%d\n" , (int )len , pss -> cwsi , vhd ? vhd -> root_process_active : -1 );
15711593 if (vhd && vhd -> root_process_active && pss -> cwsi ) {
1594+ if (len < 1024 && strstr ((const char * )in , "\"check_cert\"" )) {
1595+ struct monitor_req_args a ;
1596+ struct lejp_ctx jctx ;
1597+ memset (& a , 0 , sizeof (a ));
1598+ lejp_construct (& jctx , monitor_req_cb , & a , monitor_req_paths , LWS_ARRAY_SIZE (monitor_req_paths ));
1599+ lejp_parse (& jctx , (uint8_t * )in , (int )len );
1600+ lejp_destruct (& jctx );
1601+
1602+ if (!strcmp (a .req , "check_cert" )) {
1603+ handle_req_check_cert (vhd , pss , & a );
1604+ if (a .zone_buf ) free (a .zone_buf );
1605+ return 0 ;
1606+ }
1607+ if (a .zone_buf ) free (a .zone_buf );
1608+ }
1609+
15721610 if (len > 65536 ) {
15731611 lwsl_err ("%s: WS UI request too large\n" , __func__ );
15741612 return -1 ;
@@ -1588,53 +1626,60 @@ callback_dht_dnssec_monitor(struct lws *wsi, enum lws_callback_reasons reason,
15881626 size_t offset = lws_ptr_diff_size_t (first_brace , in ) + 1 ;
15891627 size_t out_len = 0 ;
15901628
1591- memcpy (& pss -> tx [LWS_PRE ], in , offset );
1592- out_len += offset ;
1593-
1594- int n = lws_snprintf ((char * )& pss -> tx [LWS_PRE + out_len ], 65536 - LWS_PRE - out_len , "\"jwt\":\"%s\"," , jwt_buf );
1595- out_len += (size_t )n ;
1596-
1597- if (len - offset < 65536 - LWS_PRE - out_len ) {
1598- memcpy (& pss -> tx [LWS_PRE + out_len ], first_brace + 1 , len - offset );
1599- out_len += len - offset ;
1600- pss -> tx_len = out_len ;
1601- lws_callback_on_writable (pss -> cwsi ); /* Write proxy -> root */
1602- lwsl_debug ("[INSTRUMENT] LWS_CALLBACK_RECEIVE: Enqueued proxy->root payload size %d with JWT\n" , (int )out_len );
1629+ size_t existing_len = pss -> tx_len ;
1630+ if (existing_len + offset < 65536 - LWS_PRE ) {
1631+ memcpy (& pss -> tx [LWS_PRE + existing_len ], in , offset );
1632+ out_len += offset ;
1633+
1634+ int n = lws_snprintf ((char * )& pss -> tx [LWS_PRE + existing_len + out_len ], 65536 - LWS_PRE - existing_len - out_len , "\"jwt\":\"%s\"," , jwt_buf );
1635+ out_len += (size_t )n ;
1636+
1637+ if (existing_len + out_len + len - offset + 1 < 65536 - LWS_PRE ) {
1638+ memcpy (& pss -> tx [LWS_PRE + existing_len + out_len ], first_brace + 1 , len - offset );
1639+ out_len += len - offset ;
1640+ pss -> tx [LWS_PRE + existing_len + out_len ] = '\n' ;
1641+ out_len += 1 ;
1642+ pss -> tx_len += out_len ;
1643+ lws_callback_on_writable (pss -> cwsi ); /* Write proxy -> root */
1644+ lwsl_debug ("[INSTRUMENT] LWS_CALLBACK_RECEIVE: Appended proxy->root payload size %d with JWT, total %d\n" , (int )out_len , (int )pss -> tx_len );
1645+ }
16031646 }
16041647 } else {
16051648 goto fallback ;
16061649 }
16071650 } else {
16081651fallback :
1609- memcpy (& pss -> tx [LWS_PRE ], in , len );
1610- pss -> tx_len = len ;
1611- lws_callback_on_writable (pss -> cwsi ); /* Write proxy -> root */
1612- lwsl_debug ("[INSTRUMENT] LWS_CALLBACK_RECEIVE: Enqueued proxy->root payload size %d (no JWT)\n" , (int )len );
1652+ if (pss -> tx_len + len + 1 < 65536 - LWS_PRE ) {
1653+ memcpy (& pss -> tx [LWS_PRE + pss -> tx_len ], in , len );
1654+ pss -> tx_len += len ;
1655+ pss -> tx [LWS_PRE + pss -> tx_len ] = '\n' ;
1656+ pss -> tx_len += 1 ;
1657+ lws_callback_on_writable (pss -> cwsi ); /* Write proxy -> root */
1658+ lwsl_debug ("[INSTRUMENT] LWS_CALLBACK_RECEIVE: Appended proxy->root payload size %d (no JWT), total %d\n" , (int )len + 1 , (int )pss -> tx_len );
1659+ }
16131660 }
16141661 } else {
16151662 lwsl_notice ("[INSTRUMENT] LWS_CALLBACK_RECEIVE: ABORTED! root_active=%d, pss->cwsi=%p\n" , vhd ?vhd -> root_process_active :0 , pss -> cwsi );
16161663 }
16171664 break ;
16181665
16191666 case LWS_CALLBACK_SERVER_WRITEABLE :
1620- if (vhd ) {
1621- if (vhd -> completed_checks .head ) {
1622- struct lws_dll2 * p = vhd -> completed_checks .head ;
1623- struct cert_check_result * cr = lws_container_of (p , struct cert_check_result , list );
1624- char * tx = (char * )& pss -> tx [LWS_PRE ];
1625- char * tx_end = tx + 65536 - 1 ;
1626- int n = lws_snprintf (tx , lws_ptr_diff_size_t (tx_end , tx ), "{\"req\":\"cert_status\",\"subdomain\":\"%s\",\"status\":\"%s\",\"msg\":\"%s\"}\n" ,
1627- cr -> fqdn , cr -> status_err ? "error" : "ok" , cr -> msg );
1628-
1629- if (lws_write (wsi , (unsigned char * )tx , (size_t )n , LWS_WRITE_TEXT ) < 0 )
1630- return -1 ;
1631-
1632- lws_dll2_remove (& cr -> list );
1633- free (cr );
1634- if (vhd -> completed_checks .head )
1635- lws_callback_on_writable (wsi );
1636- return 0 ;
1637- }
1667+ if (vhd && vhd -> completed_checks .head ) {
1668+ struct lws_dll2 * p = vhd -> completed_checks .head ;
1669+ struct cert_check_result * cr = lws_container_of (p , struct cert_check_result , list );
1670+ char * tx = (char * )& pss -> tx [LWS_PRE ];
1671+ char * tx_end = tx + 65536 - 1 ;
1672+ int n = lws_snprintf (tx , lws_ptr_diff_size_t (tx_end , tx ), "{\"req\":\"cert_status\",\"subdomain\":\"%s\",\"status\":\"%s\",\"msg\":\"%s\"}\n" ,
1673+ cr -> fqdn , cr -> status_err ? "error" : "ok" , cr -> msg );
1674+
1675+ if (lws_write (wsi , (unsigned char * )tx , (size_t )n , LWS_WRITE_TEXT ) < 0 )
1676+ return -1 ;
1677+
1678+ lws_dll2_remove (& cr -> list );
1679+ free (cr );
1680+ if (vhd -> completed_checks .head )
1681+ lws_callback_on_writable (wsi );
1682+ return 0 ;
16381683 }
16391684
16401685 if (vhd && vhd -> root_process_active ) {
@@ -1660,10 +1705,11 @@ callback_dht_dnssec_monitor(struct lws *wsi, enum lws_callback_reasons reason,
16601705 }
16611706 break ;
16621707
1663- case LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP :
1708+ case LWS_CALLBACK_RAW_CONNECTED :
16641709 {
16651710 struct cert_check_info * cci = (struct cert_check_info * )lws_get_opaque_user_data (wsi );
16661711 if (cci && cci -> magic == CERT_CHECK_MAGIC && vhd ) {
1712+ lwsl_notice ("[INSTRUMENT] Probe %s RAW_CONNECTED successfully!\n" , cci -> fqdn );
16671713 union lws_tls_cert_info_results ci ;
16681714 char msg [128 ];
16691715 int err = 0 ;
@@ -1705,6 +1751,7 @@ callback_dht_dnssec_monitor(struct lws *wsi, enum lws_callback_reasons reason,
17051751 void * opaque = lws_get_opaque_user_data (wsi );
17061752 struct cert_check_info * cci = (struct cert_check_info * )opaque ;
17071753 if (cci && cci -> magic == CERT_CHECK_MAGIC && vhd ) {
1754+ lwsl_notice ("[INSTRUMENT] Probe %s CLIENT_CONNECTION_ERROR: %s\n" , cci -> fqdn , in ? (char * )in : "unknown" );
17081755 struct cert_check_result * cr = malloc (sizeof (* cr ));
17091756 if (cr ) {
17101757 memset (cr , 0 , sizeof (* cr ));
@@ -1729,18 +1776,21 @@ callback_dht_dnssec_monitor(struct lws *wsi, enum lws_callback_reasons reason,
17291776 }
17301777 break ;
17311778
1732- case LWS_CALLBACK_CLOSED_CLIENT_HTTP :
1779+ case LWS_CALLBACK_RAW_CLOSE :
17331780 {
17341781 void * opaque = lws_get_opaque_user_data (wsi );
17351782 struct cert_check_info * cci = (struct cert_check_info * )opaque ;
17361783 if (cci && cci -> magic == CERT_CHECK_MAGIC ) {
17371784 cci -> magic = 0 ;
17381785 free (cci );
17391786 lws_set_opaque_user_data (wsi , NULL );
1787+ } else {
1788+ struct pss * wpss = (struct pss * )opaque ;
1789+ if (wpss ) wpss -> cwsi = NULL ;
1790+ lwsl_notice ("%s: UDS connection closed\n" , __func__ );
17401791 }
17411792 }
17421793 break ;
1743- break ;
17441794
17451795 case LWS_CALLBACK_RAW_ADOPT :
17461796 {
@@ -1774,11 +1824,29 @@ callback_dht_dnssec_monitor(struct lws *wsi, enum lws_callback_reasons reason,
17741824 vhd -> rx_len = len ;
17751825
17761826 struct pss * root_pss = (struct pss * )user ;
1777- lwsl_debug ("[INSTRUMENT] LWS_CALLBACK_RAW_RX (ROOT): Sending %d bytes to monitor request router\n" , (int )len );
1778- handle_monitor_request (vhd , root_pss , (const char * )& vhd -> rx [LWS_PRE ], len );
1827+ root_pss -> tx_len = 0 ; // Prevent synchronous overwrite buildup mapping
1828+
1829+ char * current = (char * )& vhd -> rx [LWS_PRE ];
1830+ char * end = current + len ;
1831+
1832+ while (current < end ) {
1833+ char * nl = strchr (current , '\n' );
1834+ if (!nl ) nl = end ;
1835+
1836+ size_t chunk_len = lws_ptr_diff_size_t (nl , current );
1837+ if (chunk_len > 0 ) {
1838+ char save = * nl ;
1839+ * nl = '\0' ;
1840+ lwsl_debug ("[INSTRUMENT] LWS_CALLBACK_RAW_RX (ROOT): Sending %d bytes to monitor request router\n" , (int )chunk_len );
1841+ handle_monitor_request (vhd , root_pss , current , chunk_len );
1842+ if (save != '\0' ) * nl = save ;
1843+ }
1844+ current = nl + 1 ;
1845+ }
17791846
17801847 /* Tell server socket to reply */
1781- lws_callback_on_writable (wsi );
1848+ if (root_pss -> tx_len )
1849+ lws_callback_on_writable (wsi );
17821850 }
17831851 }
17841852 break ;
@@ -1806,13 +1874,7 @@ callback_dht_dnssec_monitor(struct lws *wsi, enum lws_callback_reasons reason,
18061874 }
18071875 break ;
18081876
1809- case LWS_CALLBACK_RAW_CLOSE :
1810- {
1811- struct pss * wpss = (struct pss * )lws_get_opaque_user_data (wsi );
1812- if (wpss ) wpss -> cwsi = NULL ;
1813- lwsl_notice ("%s: UDS connection closed\n" , __func__ );
1814- }
1815- break ;
1877+
18161878
18171879 default :
18181880 break ;
@@ -1827,6 +1889,10 @@ callback_monitor_stdwsi(struct lws *wsi, enum lws_callback_reasons reason,
18271889{
18281890 uint8_t buf [2048 ];
18291891 int ilen ;
1892+ struct lws_vhost * vhost = lws_get_vhost (wsi );
1893+ const struct lws_protocols * protocol = lws_get_protocol (wsi );
1894+ struct vhd * vhd = (struct vhd * )lws_protocol_vh_priv_get (vhost , protocol );
1895+ if (!vhd && global_root_vhd ) vhd = global_root_vhd ;
18301896
18311897 switch (reason ) {
18321898 case LWS_CALLBACK_RAW_CLOSE_FILE :
0 commit comments