@@ -14,18 +14,33 @@ static spinlock_t udp_read_lock = 0;
1414 * Used by the scheduler to determine if the SOCKREAD statement
1515 * can resume execution. Returns true if still waiting.
1616 *
17- * @param proc Process being checked
18- * @param ptr Pointer containing the socket FD (cast from uintptr_t)
19- * @return true if still waiting, false if ready
17+ * For TLS-backed sockets, this consults the TLS layer to see if
18+ * decrypted bytes are pending.
19+ *
20+ * @param proc Process being checked.
21+ * @param ptr Pointer containing the socket FD (cast from uintptr_t).
22+ * @return true if still waiting, false if ready.
2023 */
21- bool check_sockread_ready (process_t * proc , void * ptr ) {
22- int64_t fd = (int64_t )(uintptr_t )ptr ;
24+ bool check_sockread_ready (process_t * proc , void * ptr )
25+ {
26+ int64_t fd ;
27+
28+ (void ) proc ; /* unused */
29+
30+ fd = (int64_t )(uintptr_t ) ptr ;
31+
2332 if (basic_esc ()) {
2433 return false;
2534 }
26- return !sock_ready_to_read ((int )fd );
35+
36+ if (tls_get (fd )) {
37+ return !tls_ready_fd (fd );
38+ }
39+
40+ return !sock_ready_to_read (fd );
2741}
2842
43+
2944/**
3045 * @brief Process SOCKREAD statement.
3146 *
@@ -35,26 +50,53 @@ bool check_sockread_ready(process_t* proc, void* ptr) {
3550 * data is available, the scheduler resumes the statement, which
3651 * reads and stores the value in a BASIC variable.
3752 *
38- * @param ctx BASIC context
53+ * For TLS-backed sockets, bytes are pulled through the TLS layer.
54+ *
55+ * @param ctx BASIC context.
3956 */
4057void sockread_statement (struct basic_ctx * ctx )
4158{
4259 char input [MAX_STRINGLEN ];
43- const char * var = NULL ;
60+ const char * var ;
61+ size_t var_length ;
62+ int64_t fd ;
63+ process_t * proc ;
64+ int rv ;
65+
66+ var = NULL ;
4467
4568 accept_or_return (SOCKREAD , ctx );
4669
47- size_t var_length ;
48- int64_t fd = basic_get_numeric_int_variable (tokenizer_variable_name (ctx , & var_length ), ctx );
70+ fd = basic_get_numeric_int_variable (tokenizer_variable_name (ctx , & var_length ), ctx );
4971 accept_or_return (VARIABLE , ctx );
5072 accept_or_return (COMMA , ctx );
5173
5274 var = tokenizer_variable_name (ctx , & var_length );
5375 accept_or_return (VARIABLE , ctx );
5476
55- process_t * proc = proc_cur (logical_cpu_id ());
77+ proc = proc_cur (logical_cpu_id ());
78+
79+ if (tls_get (fd )) {
80+ int want ;
81+ int out_n ;
82+ bool ok ;
83+
84+ want = 0 ;
85+ out_n = 0 ;
5686
57- int rv = recv ((int )fd , input , MAX_STRINGLEN , false, 100 );
87+ ok = tls_read_fd (fd , input , MAX_STRINGLEN , & want , & out_n );
88+ if (ok ) {
89+ rv = out_n ;
90+ } else {
91+ if (want == 1 ) {
92+ rv = 0 ; /* WANT_READ → would block */
93+ } else {
94+ rv = TCP_ERROR_CONNECTION_FAILED ; /* fatal TLS */
95+ }
96+ }
97+ } else {
98+ rv = recv (fd , input , MAX_STRINGLEN , false, 100 );
99+ }
58100
59101 dprintf ("sockread recv=%d\n" , rv );
60102
@@ -66,7 +108,6 @@ void sockread_statement(struct basic_ctx* ctx)
66108 return ;
67109 }
68110
69- // Clear idle state if we're resuming from IO
70111 proc_set_idle (proc , NULL , NULL );
71112
72113 if (rv < 0 ) {
@@ -75,6 +116,9 @@ void sockread_statement(struct basic_ctx* ctx)
75116 return ;
76117 }
77118
119+ if ((size_t ) rv >= sizeof (input )) {
120+ rv = (int ) (sizeof (input ) - 1 );
121+ }
78122 input [rv ] = 0 ; // Null-terminate string
79123
80124 switch (var [var_length - 1 ]) {
@@ -98,7 +142,7 @@ void sockread_statement(struct basic_ctx* ctx)
98142
99143void sockbinread_statement (struct basic_ctx * ctx )
100144{
101- accept_or_return ( SOCKBINREAD , ctx ) ;
145+ int rv ;
102146 size_t var_length ;
103147 int64_t fd = basic_get_numeric_int_variable (tokenizer_variable_name (ctx , & var_length ), ctx );
104148 accept_or_return (VARIABLE , ctx );
@@ -113,7 +157,27 @@ void sockbinread_statement(struct basic_ctx* ctx)
113157
114158 process_t * proc = proc_cur (logical_cpu_id ());
115159
116- int rv = recv ((int )fd , address , length , false, 100 );
160+ if (tls_get (fd )) {
161+ int want ;
162+ int out_n ;
163+ bool ok ;
164+
165+ want = 0 ;
166+ out_n = 0 ;
167+
168+ ok = tls_read_fd (fd , address , length , & want , & out_n );
169+ if (ok ) {
170+ rv = out_n ;
171+ } else {
172+ if (want == 1 ) {
173+ rv = 0 ; /* WANT_READ → would block */
174+ } else {
175+ rv = TCP_ERROR_CONNECTION_FAILED ; /* fatal TLS */
176+ }
177+ }
178+ } else {
179+ rv = recv ((int ) fd , (void * ) address , (uint32_t ) length , false, 100 );
180+ }
117181
118182 if (rv == 0 ) {
119183 // Not ready yet, yield and retry later
@@ -123,7 +187,6 @@ void sockbinread_statement(struct basic_ctx* ctx)
123187 return ;
124188 }
125189
126- // Clear idle state if we're resuming from IO
127190 proc_set_idle (proc , NULL , NULL );
128191
129192 if (rv < 0 ) {
@@ -136,8 +199,7 @@ void sockbinread_statement(struct basic_ctx* ctx)
136199 proc -> state = PROC_RUNNING ;
137200}
138201
139- void connect_statement (struct basic_ctx * ctx )
140- {
202+ void connect_statement (struct basic_ctx * ctx ) {
141203 char input [MAX_STRINGLEN ];
142204 const char * fd_var = NULL , * ip = NULL ;
143205 int64_t port ;
@@ -173,8 +235,47 @@ void connect_statement(struct basic_ctx* ctx)
173235 }
174236}
175237
176- void sockclose_statement (struct basic_ctx * ctx )
177- {
238+ void sslconnect_statement (struct basic_ctx * ctx ) {
239+ char input [MAX_STRINGLEN ];
240+ const char * fd_var = NULL , * ip = NULL , * sni = NULL ;
241+ int64_t port ;
242+ size_t var_length ;
243+
244+ accept_or_return (CONNECT , ctx );
245+ fd_var = tokenizer_variable_name (ctx , & var_length );
246+ accept_or_return (VARIABLE , ctx );
247+ accept_or_return (COMMA , ctx );
248+ ip = str_expr (ctx );
249+ accept_or_return (COMMA , ctx );
250+ port = expr (ctx );
251+ accept_or_return (COMMA , ctx );
252+ sni = expr (ctx );
253+
254+ const char * ca = "" ;
255+
256+ int rv = ssl_connect (str_to_ip (ip ), port , 0 , true, sni , NULL , (const uint8_t * )ca , strlen (ca ));
257+
258+ if (rv >= 0 ) {
259+ * (input + rv ) = 0 ;
260+ switch (fd_var [var_length - 1 ]) {
261+ case '$' :
262+ tokenizer_error_print (ctx , "Can't store socket descriptor in STRING" );
263+ break ;
264+ case '#' :
265+ tokenizer_error_print (ctx , "Cannot store socket descriptor in REAL" );
266+ break ;
267+ default :
268+ basic_set_int_variable (fd_var , rv , ctx , false, false);
269+ break ;
270+ }
271+
272+ accept_or_return (NEWLINE , ctx );
273+ } else {
274+ tokenizer_error_print (ctx , socket_error (rv ));
275+ }
276+ }
277+
278+ void sockclose_statement (struct basic_ctx * ctx ) {
178279 const char * fd_var = NULL ;
179280 size_t var_length ;
180281
@@ -233,15 +334,17 @@ int64_t basic_sslsockaccept(struct basic_ctx* ctx) {
233334 PARAMS_START ;
234335 PARAMS_GET_ITEM (BIP_INT );
235336 int64_t server = intval ;
337+ PARAMS_GET_ITEM (BIP_STRING );
338+ const char * cert = strval ;
339+ PARAMS_GET_ITEM (BIP_INT );
340+ const char * key = strval ;
236341 PARAMS_END ("SSLSOCKACCEPT" ,-1 );
237- /*int rv = ssl_accept(server, cert_pem, cert_len, key_pem, key_len, NULL, true);
238- if (rv == TCP_ERROR_WOULD_BLOCK) {
239- return -1;
240- } else if (rv < 0) {
342+ int rv = ssl_accept (server , (const uint8_t * )cert , strlen (cert ), (const uint8_t * )key , strlen (key ), NULL , true);
343+ if (rv < 0 ) {
241344 tokenizer_error_print (ctx , socket_error (rv ));
242345 return -1 ;
243- }*/
244- return -1 ;
346+ }
347+ return rv ;
245348}
246349
247350char * basic_insocket (struct basic_ctx * ctx ) {
@@ -334,7 +437,16 @@ void sockwrite_statement(struct basic_ctx* ctx) {
334437 accept_or_return (COMMA , ctx );
335438 const char * out = printable_syntax (ctx );
336439 if (out ) {
337- send (fd , out , strlen (out ));
440+ if (tls_get (fd )) {
441+ int want ;
442+ int out_n ;
443+
444+ want = 0 ;
445+ out_n = 0 ;
446+ tls_write_fd (fd , out , strlen (out ), & want , & out_n );
447+ } else {
448+ send (fd , out , strlen (out ));
449+ }
338450 }
339451}
340452
@@ -353,9 +465,19 @@ void sockbinwrite_statement(struct basic_ctx* ctx) {
353465 }
354466
355467 if (buffer_pointer && length ) {
356- send (fd , buffer_pointer , length );
468+ if (tls_get (fd )) {
469+ int want ;
470+ int out_n ;
471+
472+ want = 0 ;
473+ out_n = 0 ;
474+ tls_write_fd (fd , (const void * ) buffer_pointer , (size_t ) length , & want , & out_n );
475+ } else {
476+ send (fd , buffer_pointer , length );
477+ }
357478 }
358479}
480+
359481static void basic_udp_handle_packet (uint32_t src_ip , uint16_t src_port , uint16_t dst_port , void * data , uint32_t length , void * opaque ) {
360482 basic_ctx * ctx = (basic_ctx * )opaque ;
361483 if (!opaque ) {
0 commit comments