RTOS connects via TCP to Local Server, but not to Remote Server - tcp

I'm using an RTOS device and when trying to connect over TCP to a server I am running into some unusual results.
When connecting to a server on my local network, the connection is fine and I can see the packets flowing on Wire shark.
However, when attempting to connect to a remote server, one outside of my domain, the connection fails with an error code of:
TCP_ERR_NOSUCH_SOCKET (-4) --- Indicates that you have attempted to allocate a socket that
does not exist.
This occurs during connect() function:
bool CTCP::Connect( const char * ipaddr, unsigned short port ) {
IPADDR ip = AsciiToIp( ipaddr ) ;
this->m_fdnet = connect( ip, INADDR_ANY, port, TICKS_PER_SECOND * 3);
if( this->m_fdnet < 0 ) {
CLogging::Debuglogf("[TCP] Error: Connection failed, error=[%d]", getsocketerror( this->m_fdnet ) );
return false;
}
return true ;
I tried with two different remote servers, one with Google, and another one.
As a note: I am able to ping both, and both of the ports are open.
I was wondering why this is occurring.

I am a colleage of #alexfontaine and we found that this problem is actually caused by the network setup of our office and has nothing to do with the connect code above.
See this question
DHCP IP address have access to the internet but static IP address don't behind a router
Instead of deleting this question I am answering it with another question for the next person that might have this problem as well.

Related

How to make TCP socket connection work over WAN with different ISP?

I recently made a very basic TCP server application in C++ and Python using the very basic socket API. The client server connection happens flawlessly within the localhost as well as inside my LAN (within the same Wi-fi). But If I connect my client to an internet service (WAN) and try to connect to my server application behind my wifi (using the Wi-fi's public IP (provided by its ISP) and the port on which my server will be listening to) , I'm unable to get a connection. The server sits idle waiting for a connection ! I have enabled port forwarding on my Wi-fi, but still the results are all vain...
**EDIT: **
I managed to connect them over WAN, but now the ISP have to be the same... This is what I did: I made the server run on my Android device, bound it to the IP of my device that uses mobile data... The client sits behind a WiFi and connects to the Server using the previously mentioned IP and everything works fine ! But however if the client becomes an android app in another device with mobile data provided by different ISP everything fails !!! * So long as client runs behind a WiFi, but server connected to WAN (same ISP) the system works. *

s.bind((host,port)) - nodename nor servname provided, or not known in Python 3.6

On a project that included a host(me)... this was written:
and I got this :
socket.gaierror: [Errno 8] nodename nor servname provided, or not known
Here's what's supposed to happen:: https://www.youtube.com/watch?v=Cuyu3VU0yD4&frags=pl%2Cwn
Does any of you have a solution???
You should put the code snippet and the error message directly in your question.
Anyway: It is not recommended to use hostnames to bind a socket. What you actually bind sockets to are available network interfaces (which are represented by IP addresses). If you put some string into the host section in s.bind((host, port)) which is not actually a valid IPv4 or IPv6 address, the string will be replaced with the first IP address the DNS returns for that string. If you want your program to behave predictibly on all computers, use IP addresses or just bind to all interfaces.
Possible solutions:
As long as you only need the connection to work locally on your computer, use host = 'localhost' or host = '127.0.0.1'
If you want it to work within your LAN, you could just bind the socket to all available network interfaces by using host = '' or host = '0.0.0.0'. If the computer you're running the program on is a regular PC it most likely only has one network adapter besides localhost anyway. As long as you don't forward the port you are binding the socket to to your external IP address, given to you by our ISP, devices from outside your LAN will not be able to connect to that socket.
If you want to properly iterate through your available network interfaces and their corresponding IP addresses, use a library like netifaces or ifaddr.
Here is an example with ifaddr (install with pip install ifaddr):
import ifaddr
def get_available_ip_addresses():
addresses = []
for adapter in ifaddr.get_adapters():
for ip in adapter.ips:
if ip.is_IPv4:
addresses.append(ip.ip)
return addresses
This method returns a list of all IPv4 addresses of network adapters available on the computer the program is running on (as strings which can directly be used with the socket library).
s = socket.socket()
lan_addresses = [addr for addr in get_available_ip_addresses() if addr[:3] in ['10.', '172', '192']]
host = lan_addresses[0]
port = 8080
s.bind((host, port))
This will bind the socket to the first IPv4 address returned by the function I defined which lies in the conventional LAN address space. On most regular home PCs, connected to a router which provides the LAN with an internet connection, get_available_ip_addresses() as defined here will return two addresses: ['127.0.0.1', '192.x.x.x'] where the second is some address your computers network adapter has been given by your router.
Hope I could help.
Cheers,
Silas

Communicate server port to client? (TCP)

Problem
Following LuaSocket Introduction I managed to get the server running. I also managed to connect from the client side. But to get this connection the client must know the server port number. In the example code the server port is 0, which means:
If port is 0, the system automatically chooses an ephemeral port.
I guess this approach has it's advantages, but how does the poor client is supposed to know which port to connect to?
Question
How to communicate an ephemeral port number from server to client? I assume there should be no human action in the process.
Code
server (from LuaSocket Introduction)
-- load namespace
local socket = require("socket")
-- create a TCP socket and bind it to the local host, at any port
local server = assert(socket.bind("*", 0))
-- find out which port the OS chose for us
local ip, port = server:getsockname()
-- print a message informing what's up
print("Please telnet to localhost on port " .. port)
print("After connecting, you have 10s to enter a line to be echoed")
-- loop forever waiting for clients
while 1 do
-- wait for a connection from any client
local client = server:accept()
-- make sure we don't block waiting for this client's line
client:settimeout(10)
-- receive the line
local line, err = client:receive()
-- if there was no error, send it back to the client
if not err then client:send(line .. "\n") end
-- done with client, close the object
client:close()
end
client (follows this answer)
local host, port = "127.0.0.1", 100
local socket = require("socket")
local tcp = assert(socket.tcp())
tcp:connect(host, port);
--note the newline below
tcp:send("hello world\n");
while true do
local s, status, partial = tcp:receive()
print(s or partial)
if status == "closed" then break end
end
tcp:close()
How to communicate an ephemeral port number from server to client? I assume there should be no human action in the process.I assume there should be no human action in the process.
You are right. The server example is quite odd. The servers generally should bind to specific port. It shouldn't be ephemeral. So that when the server restarts the client connects to the same port as earlier. Otherwise, the clients would be at loss if server ports keeps changing.
Clients, can indeed bind to ephemeral ports ( they generally do ). Servers should be bound to specific ones.
In TCP/IP connections the server always BIND to a known port. A server is not allowed to bind to port 0. It has to be available on a known port so clients can connect to it. You should change the example to bind the server to a fixed port and then use that fixed port in the client connect function.

Unable to hear audio from Asterisk server

I am running an Asterisk server in Public IP. When I connect SIP softphones to the server, I am able to make call and conversation is possible between the softphones. However, anything that is played on the asterisk server is not heard in the softphone. In asterisk server log, I could see the message like " Playing 'hello-world.gsm' " but I could not hear any message.
Ports open for sending and receiving UDP packets in the server are 5060, 10000 to 20000, 4569, 5036 and 2727
When I setup the server inside the LAN, everything was working perfectly. So I suspect it could be related to some firewall configuration. Please help me.
Note : SIP softphones were running in a machine connected to internet using wifi dongle with Cone NAT
Just to clarify it seems like your asterisk box is on a LAN, and there is a NAT device which provides the public IP address. In this case, you should configure asterisk for network address translation.
In sip.conf set the following parameters to their correct values:
directmedia = no
nat = force_rport,comedia
canreinvite = no
insecure = port,invite
localnet =
externip/externhost =
Use the sip set debug on command to verify asterisk replaces it's local address with the externip in sip dialogs to your public clients.
Also rtp set debug on can be used to show if audio (RTP) packets are reaching the asterisk box.

Winsock2 non-local refused

(I have not put code in this question since the actual code probably doesn't matter here. If you say it does though then I can edit the question later to put it in.)
I'm new to using winsock2 or any other networking API for that matter. I have a very simple server application and client application in which the server sends a string to the client and then disconnects.
The applications work fine when I use localhost or 127.0.0.1 as the inet_addr() argument, but when I use my "real" IP, the client application just gets WSAECONNREFUSED and the server doesn't see it. I made sure that the port was the same for both applications and that also the protocol was the same.
[Edit] I have come back to this issue after abandoning networking for a while. I think this may actually have something to with the fact I am using a router, and not something in my code.
WSAECONNREFUSED is an active refusal of the connection by the peer or by an intermediate firewall. If it was the peer who issued it, it means you got the IP address or the port wrong, or else you got it right but the server isn't actually running; anyway, nothing is listening at that IP:port. If it was the firewall, adjust it.
Did you use htons() on the port number?
inet_addr() only works with IP address strings, you have to use gethostbyname() or getaddrinfo() to resolve localhost or any other hostname string to an IP address.
WSACONNREFUSED means the connection was actively refused on the remote end that you are trying to connect to.
If the server machine is refusing, that means either there is no socket listening on the requested IP:Port, or that there is one but its queue of pending client connections is full so it cannot accept a new connection at that moment.
If a router is refusing, that usually means the router is not configured to forward inbound connections for the requested IP:Port to a machine on the router's network. If you have a server running behind a router and are trying to connect to it using the router's public IP address, then the router has to be setup for port forwarding.
If a firewall is refusing, that usually means the requested port is not open.
Either way, there is no way for the client to know in code why the connection was refused. All it can do is wait for a period of time and then try again.

Resources