How to keep alive tcp socket in tcl - sockets

I have an issue,there is a piece of code which is in tcl opens a client socket in Linux. Because of my tests the socket is connection timed out after 2 hours. I'm looking for commands in tcl to keep alive the opened socket. So far I have got setsockopt,SO_KEEPALIVE all of these are in C language. Can someone help me how do we keep alive sockets in tcl.
I tried with setsockopt but it didn't worked as it is in C.I looked at tcp_keepalive_time,tcp_keepalive_intrvl,tcp_keepalive_probes which are in order 7200,75,9. I tried to modify those parameters but I dont have user permissions(admin restrictions).
if [catch {socket $use_host $use_port} comIdW] {
error "Error: Unable to connect to host $use_host port $use_port: $comIdW"
}
fconfigure $comIdW -buffering none -translation binary
set comIdR $comIdW
# I added following code based on my understanding
set optval 1
set optlen [llength $optval]
seetsockopt($comIdW,SOL_SOCKET,SO_KEEPALIVE,$optval,$optlen)
puts "SO_KEEPALIVE is ($optval ? "ON" : "OFF"))"
I wanted to keep this channel alive, it might be good If I can ping after 30 minutes of channel open

tried with setsockopt but it didn't worked as it is in C
There is currently no built-in way of setting at the script level the SO_KEEPALIVE on a socket controlled by Tcl as a Tcl channel (fconfigure). See also TIP#344.

Related

Simulate a TCP tarpit

I want to simulate test cross-platform connection failures / timeouts, starting with blocking connect()s:
#!/usr/bin/python3
import socket
s = socket.socket()
endpoint = ('localhost', 28813)
s.bind((endpoint))
# listen for connections, accept 0 connections kept waiting (backlog)
# all other connect()s should block indefinitely
s.listen(0)
for i in range(1,1000):
c = socket.socket()
c.connect(endpoint)
# print number of successfully connected sockets
print(i)
On Linux, it prints "1" and hangs indefinitely (i.e. the behavior I want).
On Windows (Server 2012), it prints "1" and aborts with a ConnectionRefusedError.
On macOS, it prints all numbers from 1 to 128 and then hangs indefinitely.
Thus, I could accept the macOS ignores the backlog parameter and just connect enough sockets for clients to block on new connections.
How can I get Windows to also block connect() attempts?
On Windows, the SO_CONDITIONAL_ACCEPT socket option allows the application to have the incoming connections wait until it's accept()ed. The constant (SO_CONDITIONAL_ACCEPT=0x3002) isn't exposed in the Python module, but can be supplied manually:
s.bind(endpoint)
s.setsockopt(socket.SOL_SOCKET, 0x3002, 1)
s.listen(0)
It's so effective that even the first connect is kept waiting.
On macOS, backlog=0 is reset to backlog=SOMAXCONN, backlog=1 keeps all connections except the first waiting.

how can I make large number of connections without error at client side

I have written a program in golang to make request about 2000qps to different remote ip with local port randomly selected by linux, and close request immediately after connection established, but still encounter bind: address already in use error periodically
what I have done:
net.ipv4.ip_local_port_range is 15000-65535
net.ipv4.tcp_tw_recycle=1 net.ipv4.tcp_tw_reuse=1 net.ipv4.tcp_fin_timeout=30
above is sockstat:
sockets: used 1200 TCP: inuse 2302 orphan 1603 tw 40940 alloc 2325 mem 201
I don't figure it out why this error still there with kernel selecting available local port,will kernel return a port in use ?
This is a good answer from 2012:
https://serverfault.com/questions/342741/what-are-the-ramifications-of-setting-tcp-tw-recycle-reuse-to-1#434669
As of 2018, tcp_tw_recycle exists only in the sysctl binary, is otherwise gone from the kernel:
https://github.com/torvalds/linux/search?utf8=%E2%9C%93&q=tcp_tw_recycle&type=
tcp_tw_reuse is still in use as described in the above answer:
https://github.com/torvalds/linux/blob/master/net/ipv4/tcp_ipv4.c#L128
However, while a TCP_TIMEWAIT_LEN is in use:
https://github.com/torvalds/linux/search?utf8=%E2%9C%93&q=TCP_TIMEWAIT_LEN&type=
the value is hardcoded:
https://github.com/torvalds/linux/blob/master/include/net/tcp.h#L120
and tcp_fin_timeout refers to a different state:
https://github.com/torvalds/linux/blob/master/Documentation/networking/ip-sysctl.txt#L294
One can relatively safely change the local port range to 1025-65535.
For kicks, if there were a situation where this client was talking to servers and network under my control, I would build a new kernel with a not-to-spec TCP_TIMEWAIT_LEN, and perhaps also fiddle with tcp_max_tw_buckets:
https://github.com/torvalds/linux/blob/master/Documentation/networking/ip-sysctl.txt#L379
But doing so in other circumstances- if this client is behind a NAT and talking to common public servers- will likely be disruptive.

Remote Logging using Log4j2

So i have this task to log activities to a file, but it has to be done
remotely on the server side, Remote logging.
NOTE : Remote Logging has to be in latest version of Log4j2(2.10)
My task was simple
Send logging info to a port.
Log info from port to a file.
My Discoveries
Socket Appender exist which help send info to a port. This is it, you dont need to create a client side code or anything.
Socket appender configuration in log4j2.properties
appender.socket.type = Socket
appender.socket.name= Socket_Appender
appender.socket.host = "IP address"
appender.socket.port = 8101
appender.socket.layout.type = SerializedLayout
appender.socket.connectTimeoutMillis = 2000
appender.socket.reconnectionDelayMillis = 1000
appender.socket.protocol = TCP
Adapting from here. But this is also log4j 1.x adaptation.
I found out that before log4j 2.6 to listen to a port we used TcpSocketServer which started a server using LogEventBridgeThis helped reach that conclusion. This class was in core.net.server which is no longer available.Assuming it is not used anymore and the only similar/closest class, TcpSocketManager.Other links that helped. How to use SocketAppend?
Then i tried this
public static final Logger LOG=LogManager.getLogger(myapp.class.getName());
main(){
LOG.debug("DEBUG LEVEL");
}
and got the following error
main ERROR TcpSocketManager (TCP:IPAddress:8111) caught exception
and will continue: java.net.SocketTimeoutException: connect timed out
I know this work because i made it read to a socket but there was no one listening, but somehow i messed up big time and there was a code change.
I need help how to go ahead. Thank You in advance
The socket server to remotely receive log events has been moved to a separate repository: https://github.com/apache/logging-log4j-tools
This still needs to be released.

how to know if a server is listening at a port

I have created a TCP socket at one end of my application. Say the end is 1. This socket closes after about 10sec. Now the other side of my application (end 2) is allowed to connect to the above created socket. Im coding this socket app in python, so suppose my end 2 is trying to connect to the TCP socket, but the socket no longer exists, my program terminates because of some exception. I dont want that to happen. It's like there is a while loop in my end 2. So if a connection is not available it goes back and wait.
Are you handling the exception correctly ..
try:
s.connect((host,port))
except socket.error, (value,message):
if s:
s.close()
print "Could not open socket: " + message
"""Code to handle a retry"""
On getting an error .. you can retry by doing a bind and listen again.. Also you need to have retry count ..say 5 and then perhaps exit.

"setsockopt SO_SNDBUF failed in tcp_connect()"

I have a problem in my C client, where I implemented a client gsoap program to invoke a web service.
Everything works fine on a Windows PC, but when I publish my code on a linux-based POS device, I receive the following error:
"setsockopt SO_SNDBUF failed in tcp_connect()"
Where should I start to debug this error, what could be the cause?
the errornum returned is 2
The code section that generates the error : (in stdsoap2.c)
if (setsockopt(sk, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int))){
soap->errnum = soap_socket_errno(sk);
soap_set_sender_error(soap,
tcp_error(soap),
"setsockopt SO_SNDBUF failed in tcp_connect()",
SOAP_TCP_ERROR);
soap->fclosesocket(soap, sk);
#ifdef WITH_IPV6
freeaddrinfo(ressave);
#endif
return SOAP_INVALID_SOCKET;
}
How big is the len argument? It's possible that the value works on Windows, but is rejected by linux for some reason. Take a look at the actual values being submitted and see if they look reasonable.
You can also try reducing this down to a very small program that just sets up a socket and tries to replicate the call to setsockopt() and see if it still fails with the SO_SNDBUF size the main program is trying to use.
well it turned out to be very simple one!!
i just had to build the c/c++ files using the binaries dedicated for linux....
gsoap(wsdl2h,soapcpp2)
windows build uses winsock and linux build uses standard sockets
and the sockets on the 2 systems are differentes!
thats why i was receiving the socket error.
hope this help others, getting this socket error msg..