If a program is running on a Linux machine, is there a way for that program to scan for ports that are allowed through the firewall? for example, if a programmer wants to make a chat system, but the program needs to know what ports aren't being refused access to incoming connections by a user's firewall, is there a way to check for this in your code? A program may not fail to bind a socket to a port even if the firewall is blocking that same port from incoming connections. Is there a way to check for open firewall ports?
Sidenote: This is purely for educational purposes and free of bad intentions, to be clear I am writing a chat system, and during testing, I was unable to connect desktop->laptop until I manually opened a port via allowing it through my firewall. This seemed a bit off to me, and unlike something that a programmer's code should require a user to do. Not to mention I don't want to leave the few people using this code at risk (if leaving a port permanently open does so). So It seems like I would be better suited finding a way to utilize ports that are already open to incoming TCP connections.
sidesidenote: all clients are running fedora
You have stumbled onto the second biggest issue governing the creation of new Internet applications nowadays. The first biggest of course is NAT, which is a strongly related issue (and hopefully going away eventually because of IPv6).
And there is no easy answer. One good answer is UPnP, but that's not an easy answer, and by no means universal. My network doesn't run it.
Another answer is to somehow tunnel everything you do over https (or http if you must). But that's a huge pain for something like a chat application.
Related
There's lots of games on Steam nowadays (Table Top Simulator, SpeedRunners) that allows people to host their own online multiplayer matches/games without the need for port forwarding.
One thing I thought of of how they do it is they simply have one server that processes all the matches as separate threads.
But then I'm starting to wonder about getting bottle necked.
I then heard these games simply somehow allow TCP to be holepunched through their NAT, getting past the need for port forwarding.
But how in say, C++ using winsock, would one do this? Or GameMaker: Studio? Or just any game in general? How do you allow people to play without port forwarding? What's the process?
I see so many games on Steam do it nowadays it must not be too complicated.
As this question is explicitely related to steam, I think it's worth mentioning the steamworks API, especially SteamNetworking. It allows peer-to-peer connection relaying through steam servers:
https://partner.steamgames.com/doc/api/ISteamNetworking
bool AllowP2PPacketRelay( bool bAllow );
Allow or disallow P2P connections to fall back to being relayed
through the Steam servers if a direct connection or NAT-traversal
cannot be established.
One may use UPnP to automatically configure the router to do the port forwarding. There's a library for that in http://pupnp.sourceforge.net/
The alternative way is to have a external server managing all traffic, so that everyone connects there, thus avoiding nat issues.
Thank you for reading my post.
Can you help me interpret what the following line from "netstat -anb" means:
Proto Local Address Foreign Address State
TCP 192.168.2.241:52440 64.233.166.103:443 ESTABLISHED
[firefox.exe]
In particular:
does this mean that the TCP port 52440 is opened on the machine which IP is 192.168.2.241?
does this mean "firefox.exe" is bound to this port?
Can you guess how "firefox.exe" knew it could use this port (without interfering with another program already bound to that port)?
As a matter of fact, "firefox.exe" is using a lot of ports.
For example, right now on 192.168.2.241, "firefox.exe" is using the ports nro 52163, 57019, 57022, 57030, 57045, 57046, 57049, 57051.
I am asking all this because I would like to write a program which binds to a TCP port to enable communication between the machine where the program is installed and a remote machine on the Internet using sockets.
Contrary to "Firefox" I need only one TCP port on the machine where the program will be installed.
I only need this mechanism to work once, the first time the program is executed (this is not a permanent feature of the program).
How can this port be chosen?
How can this port be chosen programmatically (not manually)?
If there is a firewall preventing the use of any port/the chosen port, how is the program going to behave?
Can an exception be added programmatically to the firewall to open this port?
The machine running the program is a Windows machine.
I would program this in C/C++.
Best regards.
Below is a complement to my original question.
Well, my apologies, maybe you're right: maybe it's wrong to add an exception in the firewall of the user...
What I mean by "adding an exception in the firewall of the user" is doing something like this:
netsh advfirewall firewall add rule name="An exn" dir=in action=allow protocol=TCP localport=6667 program="where/the/program/is/stored/prog.exe" enable=yes
Until now, I thought that, if an application was already "using" a TCP port for its own usage, no other application could "use" this very same port. (I'm aware of the fact that the word "use" is very imprecise. I'd be glad to be able to formulate things more accurately...)
I'm saying this because, as I need a TCP port, I was wondering if I could use an "already available" TCP port... (When I say "already available", I don't exactly know what I mean (maybe I would like to say "open" and "bindable" / or a port already "used" by another application): I'm thinking about TCP port 80 which is often "available"... Again, I wish I could be more specific about this.)
Please let me try to reformulate what I'm willing to do.
A user runs a program "setup.exe" on its machine "M".
"setup.exe" sends a message "m1" to an Internet remote server "RS".
"RS" sends back some information "m2" to "setup.exe" running on machine "M" through a TCP port.
To be able to allow this bidirectional communication between "M" and "RS", I need to "have" a TCP port on machine "M" from which "setup.exe" can receive information sent by "RS". ("RS" is not a problem to me, I can do anything I want on it).
Given the fact that I know nothing about "M" a priori apart from the fact that it is a Windows machine (in particular I do not know what kind of firewall protects it, etc.), I don't really know how to handle the problem correctly. What I would like to avoid is having "setup.exe" fail silently without telling why the TCP port on machine "M" can't be "used".
Given the fact that I need to "have a TCP port available" for the program "setup.exe" running on machine M, what steps should I follow to make it as smooth as possible for the user.
Suppose I'm trying to "use" TCP port 6667, and suppose I'm not "allowed" to.
Apart from a firewall, or another application already "using" this port, what could be the reasons why this port is not available?
I simulated the two machines "M" and "RS" basically using this code http://msdn.microsoft.com/en-us/library/windows/desktop/ms737889%28v=vs.85%29.aspx.
I didn't add an exception to "M"'s firewall.
The two programs on machines "M" and "RS" could communicate smoothly and correctly.
But as you pointed it out in your first answer, "there are no outbound port rules in the firewall at all" on these test machines...
So, I tried, as a simulation, to add an exception into the M's firewall in the section "Outbound rules" to block completely the connection to port TCP 6667 on machine "M": the scenario described above (steps 1) 2) 3)) fails in that case.
I hope this literature is not too indigestible and sorry for the approximations and misunderstandings.
Thank you for helping. Best regards.
does this mean that the TCP port 52440 is opened on the machine which IP is 192.168.2.241?
Possibly, but more probably it means there are no outbound port rules in the firewall at all, as there shouldn't be, being pointless.
does this mean "firefox.exe" is bound to this port?
It means that socket of firefox.exe is bound to that port. It can have many other sockets, and usually does.
I would like to write a program which binds to a TCP port to enable communication between the machine where the program is installed and a remote machine on the Internet using sockets.
You need to state whether your program is a client or a server. If it's a client, it's exactly like Firefox, and you don't have a problem. If it's a server, you have to bind to a port that is open for incoming in your firewall, and Firefox is completely and utterly irrelevant.
Contrary to "Firefox" I need only one TCP port on the machine where the program will be installed.
Sounds like a server, but you need to tell us. For simplicity I am assuming it's a server from here on.
I only need this mechanism to work once, the first time the program is executed (this is not a permanent feature of the program).
You don't need this mechanism to work at all. You need the user to open the port. The user won't appreciate software that breaks his firewall configuration, assuming you can do it at all, which you shouldn't.
How can this port be chosen?
By you. Choose it now. Use one that isn't reserved by IANA.
How can this port be chosen programmatically (not manually)?
You can specify port zero but then you have to tell the user so he can open it at the firewall.
If there is a firewall preventing the use of any port/the chosen port, how is the program going to behave?
Incoming connections won't succeed so the program will do nothing.
Can an exception be added programmatically to the firewall to open this port?
No idea, but it's a bad idea, see above.
Let's say I have a server, and two clients connected to it. (via TCP, but it doesn't matter)
My goal is to allow a direct connection between those two clients. This is to allow direct voice contact between two players, for example, or any other client plugin they may have installed which don't need server interaction (like playing some kind of random game between the two). The server can be there to help setting up the connection.
From duskwuff's answer, I got several leads:
http://en.wikipedia.org/wiki/STUN which describes an algorithm to do that, and
http://en.wikipedia.org/wiki/UDP_hole_punching
From those, I got more leads:
http://www.h-online.com/security/features/How-Skype-Co-get-round-firewalls-747197.html
http://nutss.gforge.cis.cornell.edu/stunt.php -- A possible STUN implementation with TCP
With time, I could surely work out something for my program. For now I'm using C++ and TCP (Qt Sockets or Boost sockets), but if needed I don't mind doing UDP in C and wrapping it.
The bounty is there for any programmer having experience with those in C and C++ that may give tips to make this easier, by linking to example programs, updated libraries, or any other useful information. A documented, flexible & working C++ TCP implementation would be the best but I'll take what I get!
Punching TCP holes in NAT is sometimes/often possible (it depends of the NAT behavior). This is not a simple subject to learn, but read the corresponding chapter about NAT traversal from Practical JXTA II (available online on Scribd) to understand the nature of the issues to solve.
Then, read this. It comes from the guy who wrote that: http://nutss.gforge.cis.cornell.edu/stunt.php (one of the links in your question).
I am not a C/C++ specialist, but the issues to solve are not language specific. As long as you have access to TCP from your code base, that's enough. Keep in mind that implementing UDP traversal is easier than TCP.
Hope these tips help.
P.S.: I am not aware of a C/C++ implementation of the solution. The code mentioned in Cornell's link is NOT operational as confirmed by the author. I tried to resuscitate it myself, but he let me know it was completely tweaked for research purposes and far from production ready.
I'm not aware of any way to reliably punch through firewalls for TCP, but there's a similar method for UDP traffic that's pretty well documented:
http://en.wikipedia.org/wiki/STUN
http://en.wikipedia.org/wiki/UDP_hole_punching
A few links to projects that might be of interest or helpful:
http://sourceforge.net/projects/stun/
http://udt.sourceforge.net/
http://www.telehash.org/
You're looking for rendezvous server for NAT hole punching: the server that is publicly accessible (not behind NAT/firewall or they are properly configured) to help computers behind NAT/firewall to establish peer-to-peer connection.
UDP is more popular in NAT punching because provides much better results than TCP. Clear and informative description of UDP NAT hole punching can be found here.
If you need reliable communication, you can use reliable protocols over UDP:
SCTP (libraries) - standardized one, or
one of many custom protocols, e.g. RakNet (I used this library, it's quite mature and feature-rich and has NAT punching implementation), Enet or many others (Q8)
Ephemeral ports won't magically eliminate the need to relay through the server, because they are only valid during the life of the session opened through a well known service port. Basically ephemeral ports depend on a server session.
You will need to use the server to relay communications between both clients, that is act as a proxy server. One option would be to setup a SSH tunnel through a SSH proxy server, with the added benefit of security.
Still this doesn't guarantee that the firewall won't block the connection. That depends on the firewall type and configuration. Most residential routers that act as firewalls, by default block all incoming connections. This is normally fine because most of the time the computers behind the firewall act only as clients, which initiate the connections to the outside. And this setup varies, because some restrict initiating connections only to well known service ports like HTTP, HTTPS, FTP, SFTP, SSH, etc., and if your proxy server uses a non-well-known-service port then the connection will be blocked.
But firewalls can be setup to block outgoing traffic also, this is most common in corporate networks, which don't even allow direct connections to web servers and route everything through proxy servers, in order to control resource usage.
You can also research on the use of UPnP to open ports dynamically.
I have a .NET application and, as you know, the process of connecting to FTP (port 21) using C# is relatively easy, but I am unable to connect. I think it's an ISP issue, because the last time I logged in was like six months ago, and it all worked fine. I have also turned off all firewalls, but same thing happens. I can't even do it through a web browser. Is it common for us ISPs to block outbound connections?
I am using Verizon.
Blocking outgoing SMTP is quite common.
I haven't heard of any major ISP blocking FTP, but that doesn't mean it doesn't happen. It seems unlikely though.
More likely is that you are running behind a NAT system and need to use PASV to turn on passive mode. If both server and client are behind NAT gateways, it is probably too much work to get FTP working to justify continuing to use it.
Might I suggest that now would be a good time to migrate to SFTP? It is a much nicer protocol in many respects: there is a standard filename display (rather than just using whatever the ls(1) or DIR command output looks like), it does not require active vs passive silliness, and it does not require ascii vs binmode silliness.
I need to write a win32 c/c++ application which will be able to determine whether the PC it's running on is connected to one of 2 networks. The first network is the company LAN (which has no internet connection) and the second network is a standalone switch with a single PC connected to it (the PC that the program is running on).
I'm pretty new to network programming but so far I have tried testing to see if a network drive which is held on our LAN can be mapped. This works fine if the PC is connected to the LAN, the drive mapping succeeds so so LAN detection is successful. However, if the PC is connected to the switch, this results in a VERY long timeout which is not a suitable as it will delay the program so much as to make it unusable.
Does anyone have any alternative suggestions?
I'm using c/c++ in VS 6.0
[Update]
Whilst trying a few different ideas and looking at some of the suggestions below I thought I should update with some additional information as many (if not all) of the suggestions I don't think will work.
(1) The aforementioned LAN has no external connections at all, it is completely isolated so no resolving of external DNS or pinging websites is possible.
(2) Hostname, MAC address, IP, Default Gateway, Subnet etc etc (basically everything you see in ipconfig -all) are all manually configured (not dynamic from the router) so checking any of these settings will return the same whether connected to the LAN or the switch.
(3) Due to point (2), any attempts to communicate with the switch seem to be unsuccessful, in fact almost all networking commands (ping, arp etc) seem to fail - I think due to the machine trying to connect to the LAN when it isn't there :-(
One thing I have found which works is pinging the default gateway IP which times out when connected to the switch. This is sort of ok as I can reduce the timeout of ping so it doesn't just hang for ages but it feels like a bit of a hack and I would certainly appreciate any better solutions.
Thanks
As far as TCP/IP is concerned there is no such thing as a LAN on WAN. There are a set of non-internet routable addresses like 192.168.x.x and 10.x.x.x but these are sometimes used by ISP short of IP addresses.
You best bet is to use Asynchronous APIs when making TCP/IP connections. WIN32 defines a whole buch of OVERLAPPED APIs for this purpose. This will prevent your application from grinding to a halt while waiting for a remote connection.
Alternatively put the socket stuff into another thread and then only notify the UI when the operation is done.
I would first try to differentiate between the two using information available locally--that is, from your computer. Does the output of ipconfig /all differ depending on which network you're connected to? If so, exploit that difference if you can.
Is it possible to get the MAC address of the standalone switch? Of the switch that controls the company LAN? That would be a sure way to tell. Unless somebody cloned the MAC address.
If you try using the existence or non-existence of some network service to determine which network you're connected to, you can never be sure. For example, if you failed to map that network drive, all you know is that the network drive isn't available. You can't say for certain that you're not connected to the company LAN. Same is true if you use ping. Lack of response from a particular machine means only that the machine didn't respond.
Various things you can look at for differentiation:
DNS domain name (GetComputerNameEx)
MAC address of gateway (ping it, then GetIpNetTable)
Routing table(do you have a gateway and default route on the company LAN)
WNet discovered network resources (WNetOpenEnum, WNetEnumResource)
Ability to resolve external hostnames (try a 5-10 names like www.google.com, www.microsoft.com and so on, if one resolves you should have internet)
You'll have to decide how many indicators are "enough" to decide you're on one or the other LAN though if tests fail. Then keep retrying until you have a definite result.
http://msdn.microsoft.com/en-us/library/aa366071%28v=VS.85%29.aspx has a lot of network related functions that you can experiment with to create further indicators.