Sysop: | Amessyroom |
---|---|
Location: | Fayetteville, NC |
Users: | 26 |
Nodes: | 6 (0 / 6) |
Uptime: | 51:33:42 |
Calls: | 632 |
Files: | 1,187 |
D/L today: |
21 files (18,502K bytes) |
Messages: | 178,040 |
Hi,
i'v running an encrypted client/server network application with tcltls over xmlrpc protocol. It's implemented with coroutines and normaly runs without
a problem.
Now i have 2 instances where on both sides the network connection is a bit unstable. I observed that after some vague time the communication hangs and after restarting the application it runs again for a vague time and the
error comes back.
So i build an test scenario under linux here and try to simulate the
unstable connection with time changed iptables commands. My debugging now show, that the hanging point is the tls::handshake command. It is an ansynchrous tcp connection, so the the tls::handshake command should come back and return an value. But in the case of the problem, it does not come back and runs forever, so the application hangs.
Would it be possible to integrate an "-timeout" option into tcltls handshake to overcome these problem ?
I am running tcltls V1.7.22 on tcl V8.6.16.
Any ideas are welcome ...
best regards
Michael
On 14/10/2025 13:50, Michael Niehren wrote:
Hi,
i'v running an encrypted client/server network application with tcltls
over
xmlrpc protocol. It's implemented with coroutines and normaly runs
without
a problem.
Now i have 2 instances where on both sides the network connection is a
bit
unstable. I observed that after some vague time the communication
hangs and
after restarting the application it runs again for a vague time and the
error comes back.
So i build an test scenario under linux here and try to simulate the
unstable connection with time changed iptables commands. My debugging now
show, that the hanging point is the tls::handshake command. It is an
ansynchrous tcp connection, so the the tls::handshake command should come
back and return an value. But in the case of the problem, it does not
come
back and runs forever, so the application hangs.
Would it be possible to integrate an "-timeout" option into tcltls
handshake
to overcome these problem ?
I am running tcltls V1.7.22 on tcl V8.6.16.
Any ideas are welcome ...
best regards
-a-a Michael
difficult to say without full source code, but I never managed to make TclTLS work with async sockets, so in my project I switch the TCP socket
to the sync mode just to perform a TLS handshake, and then switch it to async again:
chan configure $sock -blocking 1
tls::import $sock -require 1 -command tls_callback (+other options if needed)
tls::handshake $sock
chan configure $sock -blocking 0
tls_callback can be useful for error reporting
Note that version 1.7 is very insecure due to this bug https://core.tcl- lang.org/tcltls/tktview/3c42b2ba11
so if possible upgrade to v2.0.b2 where it is fixed
Best regards,
Petro
On 14/10/2025 18:56, Petro Kazmirchuk wrote:
On 14/10/2025 13:50, Michael Niehren wrote:
Hi,
i'v running an encrypted client/server network application with
tcltls over
xmlrpc protocol. It's implemented with coroutines and normaly runs
without
a problem.
Now i have 2 instances where on both sides the network connection is
a bit
unstable. I observed that after some vague time the communication
hangs and
after restarting the application it runs again for a vague time and the
error comes back.
So i build an test scenario under linux here and try to simulate the
unstable connection with time changed iptables commands. My
debugging now
show, that the hanging point is the tls::handshake command. It is an
ansynchrous tcp connection, so the the tls::handshake command should
come
back and return an value. But in the case of the problem, it does
not come
back and runs forever, so the application hangs.
Would it be possible to integrate an "-timeout" option into tcltls
handshake
to overcome these problem ?
I am running tcltls V1.7.22 on tcl V8.6.16.
Any ideas are welcome ...
best regards
-a-a Michael
difficult to say without full source code, but I never managed to
make TclTLS work with async sockets, so in my project I switch the
TCP socket to the sync mode just to perform a TLS handshake, and then
switch it to async again:
chan configure $sock -blocking 1
tls::import $sock -require 1 -command tls_callback (+other options if
needed)
tls::handshake $sock
chan configure $sock -blocking 0
tls_callback can be useful for error reporting
Note that version 1.7 is very insecure due to this bug
https://core.tcl- lang.org/tcltls/tktview/3c42b2ba11
so if possible upgrade to v2.0.b2 where it is fixed
Best regards,
Petro
in fact, looking at the newsgroup discussion from 2 days ago, the new version might fix your unstable connection
Yes, the 2.0b2 release has many improvements in this area. Please try it
and let us know if it resolves the issue. Remember to use 'package
prefer latest' before 'package require tls' to ensure you use the beta release. Thanks.
https://core.tcl-lang.org/tcltls/uv/tcltls-2.0b2.tar.gz
Brian wrote:
Yes, the 2.0b2 release has many improvements in this area. Please try itHi,
and let us know if it resolves the issue. Remember to use 'package
prefer latest' before 'package require tls' to ensure you use the beta
release. Thanks.
https://core.tcl-lang.org/tcltls/uv/tcltls-2.0b2.tar.gz
i've checked it with 2.0b2 and run into the same problem. But i found an
easy way to reproduce the problem. But you have to be on a linux machine. Take the following tcl code:
#!/usr/bin/tclsh
puts "tcltls version [package require tls]"
set ::connected 0
set sock [socket -async 192.168.70.240 2005]
chan event $sock writable {set ::connected 1}
vwait ::connected
puts "connected"
tls::import $sock -require 0
puts "wait 5 seconds to deny traffic with iptables"
after 5000
puts "start handshake"
set erg 0
set timeout 5
while {$erg == 0 && $timeout != 0} {
if [catch {set erg [tls::handshake $sock]} msg] {
puts "error: $msg"
after 1000
incr timeout -1
}
}
puts "erg: $erg"
At the moment where you see the wait message you have to set the iptables rule in another shell: iptables -I INPUT -s 192.168.70.240 -j DROP
Then you see the "start hanshake" and it hang's. The problem occurs also if
i ommit the -async option.
hope that help's
Michael
I can't test it the same way since I don't know what's running at that host/port, but without a service running I don't get a response. So
since the socket is in blocking mode, it blocks forever. I added
'fconfigure $sock -blocking 0' after the set sock line and that gets
things moving. In debug mode (add a " --enable-debug" to configure), I
can see it goes into an infinite loop due to errno 11=resource
temporarily unavailable. So not sure if that's what you see, but the
root issue is the sever isn't responding and the socket doesn't fail
with a fatal error since currently, errno==11 is a retry condition so it
will loop forever attempting to connect. I could add a -retry count
limit option, but my suggestion is to add a timer to time-out after the socket setup but before tls::import. If it times out (connected == -1
below), then abort. This avoids calling tls and waiting on it.
I can't test it the same way since I don't know what's running at that host/port, but without a service running I don't get a response. So
since the socket is in blocking mode, it blocks forever. I added
'fconfigure $sock -blocking 0' after the set sock line and that gets
things moving. In debug mode (add a " --enable-debug" to configure), I
can see it goes into an infinite loop due to errno 11=resource
temporarily unavailable. So not sure if that's what you see, but the
root issue is the sever isn't responding and the socket doesn't fail
with a fatal error since currently, errno==11 is a retry condition so it
will loop forever attempting to connect. I could add a -retry count
limit option, but my suggestion is to add a timer to time-out after the socket setup but before tls::import. If it times out (connected == -1
below), then abort. This avoids calling tls and waiting on it.
I can't test it the same way since I don't know what's running at that host/port, but without a service running I don't get a response. So
since the socket is in blocking mode, it blocks forever. I added
'fconfigure $sock -blocking 0' after the set sock line and that gets
things moving. In debug mode (add a " --enable-debug" to configure), I
can see it goes into an infinite loop due to errno 11=resource
temporarily unavailable. So not sure if that's what you see, but the
root issue is the sever isn't responding and the socket doesn't fail
with a fatal error since currently, errno==11 is a retry condition so it
will loop forever attempting to connect. I could add a -retry count
limit option, but my suggestion is to add a timer to time-out after the socket setup but before tls::import. If it times out (connected == -1
below), then abort. This avoids calling tls and waiting on it.
Maybe someone can explain the difference of an sync channel with
blocking on or off and an async channel with blocking on or off ...
that's not clear to me.
Michael Niehren <michael@niehren.de> wrote:
Maybe someone can explain the difference of an sync channel with
blocking on or off and an async channel with blocking on or off ...
that's not clear to me.
I've always understood the difference to be that the "-blocking on/off" setting is the control as to whether a channel is 'sync' or 'async'.
I.e., that a 'sync' channel is a blocking channel, and that an 'async' channel is a non-blocking channel.
So a 'sync channel with blocking on' is just a 'sync channel'.
A 'sync channel with blocking off' is (while -blocking is off) an
'async channel'.
And, as well, the converse for 'async with -blocking on/off'.
I can't test it the same way since I don't know what's running at that host/port, but without a service running I don't get a response. So
since the socket is in blocking mode, it blocks forever. I added
'fconfigure $sock -blocking 0' after the set sock line and that gets
things moving. In debug mode (add a " --enable-debug" to configure), I
can see it goes into an infinite loop due to errno 11=resource
temporarily unavailable. So not sure if that's what you see, but the
root issue is the sever isn't responding and the socket doesn't fail
with a fatal error since currently, errno==11 is a retry condition so it will loop forever attempting to connect. I could add a -retry count
limit option, but my suggestion is to add a timer to time-out after the socket setup but before tls::import. If it times out (connected == -1 below), then abort. This avoids calling tls and waiting on it.
Rich wrote:
Michael Niehren <michael@niehren.de> wrote:
Maybe someone can explain the difference of an sync channel with
blocking on or off and an async channel with blocking on or off ...
that's not clear to me.
I've always understood the difference to be that the "-blocking on/off"
setting is the control as to whether a channel is 'sync' or 'async'.
I.e., that a 'sync' channel is a blocking channel, and that an 'async'
channel is a non-blocking channel.
So a 'sync channel with blocking on' is just a 'sync channel'.
A 'sync channel with blocking off' is (while -blocking is off) an
'async channel'.
And, as well, the converse for 'async with -blocking on/off'.
But that seem's not to be the reality:
If i open a channel with -async and ask with
fconfigure $sock -blocking
the blocking value, it is set to 1, that's the default.
it's ab bit obscure ...
Am 15.10.2025 um 02:16 schrieb Brian:
I can't test it the same way since I don't know what's running at that
host/port, but without a service running I don't get a response. So
since the socket is in blocking mode, it blocks forever. I added
'fconfigure $sock -blocking 0' after the set sock line and that gets
things moving. In debug mode (add a " --enable-debug" to configure), I
can see it goes into an infinite loop due to errno 11=resource
temporarily unavailable. So not sure if that's what you see, but the
root issue is the sever isn't responding and the socket doesn't fail
with a fatal error since currently, errno==11 is a retry condition so
it will loop forever attempting to connect. I could add a -retry count
limit option, but my suggestion is to add a timer to time-out after
the socket setup but before tls::import. If it times out (connected ==
-1 below), then abort. This avoids calling tls and waiting on it.
If tcltls requires -blocking 0 in the connect phase, wouldnt it be
possible to set this by TCLTLS?
The channel driver code is very complicated.
Blocking means, that, for example, a read for 1 byte will block until 1
byte is received or if an error occured.
Async means for me, that a file event is active.
Harald
* Rich <rich@example.invalid>
| Michael Niehren <michael@niehren.de> wrote:
| > Maybe someone can explain the difference of an sync channel with
| > blocking on or off and an async channel with blocking on or off ...
| > that's not clear to me.
| I've always understood the difference to be that the "-blocking on/off"
| setting is the control as to whether a channel is 'sync' or 'async'.
| I.e., that a 'sync' channel is a blocking channel, and that an 'async'
| channel is a non-blocking channel.
| So a 'sync channel with blocking on' is just a 'sync channel'.
| A 'sync channel with blocking off' is (while -blocking is off) an
| 'async channel'.
| And, as well, the converse for 'async with -blocking on/off'.
Hmmm, maybe I'm on a complete wrong path here, but in my understanding "sync/async" and "blocking/non-blocking" refer to different 'stages' of
the socket: "sync/async" refers to the establishment of the connection, whereas "blocking/non-blocking" refers to the communication once the
socket is established.
- socket host port (ie 'sync')
blocks while the connection is tried (you have no way to specify
blocking/non-blocking at this stage). When the command returns, the
connection is either established, or the connection has failed.
- socket -async host port (ie 'async')
returns immediately (does not block) while the connection is tried in
the background. Success or failure of the connection has to be
determined by other means (writeable fileevent, querying the
connection status by [chan configure] etc)
Only after the connection has been established, one can set blocking/non-blocking which has the usual meaning for read/write
requests on the socket. sync/async has no relevance once the connection
is established.
R'