c linux sockets: check for existing connections from client side - c

I have the following setup:
2 Ubuntu machines (server and client)
on the "server" I'm running this to echo all the data received back to the sender (the client):
ncat -e /bin/cat -v -l 12345
on the client I have simple application which just connects to the remote socket: socket() -> setsockopt() -> connect()
So... my question is: Is it possible to check if there are other applications already connected to the socket from the client application? I want only one process connected to the socket at any given time and I want to check this from the client application. Is this possible? After 3h googling I couldn't find anything relevant :(
(sorry, no experience with network programming)

No, a client is not able to see how many other clients are connected to a server.
To be able to retrieve this information an application specific protocol needs to be used on client and server.
Anyhow there is this one special case: If the client knows that a maximum of N clients can connect to the server, and it's own try to connect is refused it could assume that N clients are connected to the server already.
To set the maximum number of connections ncat handles in parallel use it's option -m/--max-conns. Verbatim form man ncat:
-m numconns, --max-conns numconns (Specify max number of connections) .
The maximum number of simultaneous connections accepted for an Ncat instance. 100 is the default.

Run:
netstat -an | grep <your server port port number>
on your client machine to see any existing TCP connections.

Can you not close the listening socket on the server after you've accepted one client? If there's no listening socket no more clients will be able to connect. Once you've dropped your one client, you can then open the listening socket again, ready for one more. That way the client will see a "failure" to connect if the server is busy, or will succeed normally otherwise.
The down side of this approach is that the client won't be able to determine exactly why it can't connect, it could be because the client is busy (has its one client) or it could be because of other issues. Does this matter?

Related

Checking if server process is listening on domain socket or not

I'm writting client-server programs, that using unix domain socket for communicating between two sides.
The requirement is:
Server opens an abstract socket on a given address, then listen on that. By some triggers, server can stop listening on that.
Client has to monitor that Server is listening on given address path or not
if server is listening on socket then send a register request to server
if server close the socket then do some action cleaning up...
To check the server is listening or not, my solution is:
Periodically create a socket and connect to server address path, if succeed, then means that server is listening, and vice versa for any case of error.
But the solution seems to be cpu-consuming if checking interval is too short.
Then my question is: do we have any method like registering some callback to system, and get the notification whenever some process starts/stops listening on a given address? or some other better suggestion...??
Many thanks,

Can a server directly connect two sockets that it is connected to?

Say I have a public server on the Internet, written in C, that is connected to two independent clients. Both clients initiated the connection. One client is (e.g.) an iOS app, the other is a native Windows app.
The purpose of my server is to allow these clients to send text messages to each other. Client 1 sends a message, the server receives it, and then forwards it onto Client 2. The same thing happens in reverse when Client 2 sends a message.
This feels inefficient. What I would really like is for both of these connections to contact the server and then for the server to connect these two clients directly to each other - after which my server can forget both clients as they are responsible for communicating with each other. My server is then free to connect up other clients in the same way.
My question is: is this even possible (with TCP and/or UDP)? Neither client necessarily has a public IP address, which is why they have to initiate the connection. Once the connection is established however, my server knows the connection address of both clients. Is there a way to connect them together? A syscall that can do this sort of thing, perhaps?
No, you can not join two existing TCP connections to one.
There are 2 options:
1) Keep your server in the middle as it already is. It should not be problem, if you don't have thousands of clients under one server.
2) Server could send control messages to clients, and order those open new TCP connection between each other. Server should also make decision which of the two clients must be initiator of the new TCP connection.
Option 2 is problematic, because client may have firewall rule that prevents in coming connection to the wanted port. Also NAT would cause problems.

How to establish a connection to a database using TCP?

I'm trying to establish TCP connection with PostgreSQL 9.1 server via Microsoft telnet. but When the connection has been establishe I received
Jconnector 3.6 1 ♥
What does it mean? Is it opssible at all to establish such connection manually to communicate the database via TCP?
When a TCP connection to a port is opened, what is listening on the Port sometimes announces itself: in this case, what is listening is Jconnector 3.6.1. The heart-shape is some binary data.
TCP connections tend to be only used by program code, as 'conversations' at that level quite often involve binary data. I don't know what Postgres does, but if you get it to run a select and return the data it will very likely be all binary and quire unreadable by a human.
If you search for what the wire-protocol is for Postgres, you may be able to make it do something via a telnet session, but expect you'd have a lot of difficulty.

Connection time out of TCP write (netstat shows ESTABLISHED)

I made an experiment:
A server listens on port 8804 accepts a connection of a client and then send data to the client endless. I shutdown the network.
When I run netstat -anotp | grep 8804 ,it shows that the connection is "ESTABLISHED" on both server and client , but there is no data transmission.
After a while , the server throw an error : "Connection time out"
netstat -anotp | grep 8804 and found that the client is still "ESTABLISHED"
So:
1. Why does the server which is blocked on the system call "write" throw the "Connection timeout" error. Why not the client ?
2. How to let the client find the connection is shutdown actually.
3. Why are the server and client's statuses both "ESTABLISHED" when the network does not work ?
Thanks for your answer !
Your server is expecting TCP ACKs for individual data segments that it sends to the client; however, the client has no idea how long the server's data is. Since you shutdown the network the server no longer gets ACKs from the client. Result: Connection timeout on the server (See Note 1)
Use TCP Keepalives on your socket (See Note 2)
You have not enabled TCP Keepalives. If you are using python, you can do so like this (assuming your socket is named s):
# Do this before you accept() anything on the socket
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
EDIT:
Since you're using C, a link to the Linux TCP Keepalives Howto
NOTES
RFC 1122: Section 4.2.3.5 "TCP Connection Failures"
RFC 1122: Section 4.2.3.6 "TCP Keepalives"

What can be the reasons of connection refused errors?

I'm trying to write a server program in C,
using another client, I get this error when I try to connect through port 2080 for example.
connection refused
What can be the reasons of this error?
There could be many reasons, but the most common are:
The port is not open on the destination machine.
The port is open on the destination machine, but its backlog of pending connections is full.
A firewall between the client and server is blocking access (also check local firewalls).
After checking for firewalls and that the port is open, use telnet to connect to the ip/port to test connectivity. This removes any potential issues from your application.
The error means the OS of the listening socket recognized the inbound connection request but chose to intentionally reject it.
Assuming an intermediate firewall is not getting in the way, there are only two reasons (that I know of) for the OS to reject an inbound connection request. One reason has already been mentioned several times - the listening port being connected to is not open.
There is another reason that has not been mentioned yet - the listening port is actually open and actively being used, but its backlog of queued inbound connection requests has reached its maximum so there is no room available for the inbound connection request to be queued at that moment. The server code has not called accept() enough times yet to finish clearing out available slots for new queue items.
Wait a moment or so and try the connection again. Unfortunately, there is no way to differentiate between "the port is not open at all" and "the port is open but too busy right now". They both use the same generic error code.
If you try to open a TCP connection to another host and see the error "Connection refused," it means that
You sent a TCP SYN packet to the other host.
Then you received a TCP RST packet in reply.
RST is a bit on the TCP packet which indicates that the connection should be reset. Usually it means that the other host has received your connection attempt and is actively refusing your TCP connection, but sometimes an intervening firewall may block your TCP SYN packet and send a TCP RST back to you.
See https://www.rfc-editor.org/rfc/rfc793 page 69:
SYN-RECEIVED STATE
If the RST bit is set
If this connection was initiated with a passive OPEN (i.e., came
from the LISTEN state), then return this connection to LISTEN state
and return. The user need not be informed. If this connection was
initiated with an active OPEN (i.e., came from SYN-SENT state) then
the connection was refused, signal the user "connection refused". In
either case, all segments on the retransmission queue should be
removed. And in the active OPEN case, enter the CLOSED state and
delete the TCB, and return.
Connection refused means that the port you are trying to connect to is not actually open.
So either you are connecting to the wrong IP address, or to the wrong port, or the server is listening on the wrong port, or is not actually running.
A common mistake is not specifying the port number when binding or connecting in network byte order...
Check at the server side that it is listening at the port 2080.
First try to confirm it on the server machine by issuing telnet to that port:
telnet localhost 2080
If it is listening, it is able to respond.
1.Check your server status.
2.Check the port status.
For example 3306 netstat -nupl|grep 3306.
3.Check your firewalls.
For example add 3306
vim /etc/sysconfig/iptables
# add
-A INPUT -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCEPT
Although it does not seem to be the case for your situation, sometimes a connection refused error can also indicate that there is an ip address conflict on your network. You can search for possible ip conflicts by running:
arp-scan -I eth0 -l | grep <ipaddress>
and
arping <ipaddress>
This AskUbuntu question has some more information also.
I get the same problem with my work computer.
The problem is that when you enter localhost it goes to proxy's address not local address you should bypass it follow this steps
Chrome => Settings => Change proxy settings => LAN Settings => check Bypass proxy server for local addresses.
In Ubuntu, Try
sudo ufw allow <port_number>
to allow firewall access to both of your server and db.
From the standpoint of a Checkpoint firewall, you will see a message from the firewall if you actually choose Reject as an Action thereby exposing to a propective attacker the presence of a firewall in front of the server. The firewall will silently drop all connections that doesn't match the policy. Connection refused almost always comes from the server
In my case, it happens when the site is blocked in my country and I don't use VPN.
For example when I try to access vimeo.com from Indonesia which is blocked.
Check if your application is bind with the port where you are sending the request
Check if the application is accepting connections from the host you are sending the request, maybe you forgot to allow all the incoming connections 0.0.0.0 and by default, it's only allowing connections from 127.0.0.1
I had the same message with a totally different cause: the wsock32.dll was not found. The ::socket(PF_INET, SOCK_STREAM, 0); call kept returning an INVALID_SOCKET but the reason was that the winsock dll was not loaded.
In the end I launched Sysinternals' process monitor and noticed that it searched for the dll 'everywhere' but didn't find it.
Silent failures are great!

Resources