Comcast blocks port 1080 inbound

I recently switched to Comcast internet, and it works fine, but my Arduino IoT loggers started to experience occasional connect failures when sending data to online database services. After a week of spinning wheels, jumping to bad conclusions, barking up wrong trees, and not recognizing evidence that pointed to the actual problem, I finally realized that Comcast blocks inbound traffic on port 1080.

EthernetClient.cpp starts with port 1024, increments it for every connect, then when it rolls over from 65535 to zero, it bumps it back to 1024. When trying to use port 1080, it sends the initial SYN but nothing ever comes back, so it times out after ~30 seconds.

Here is a patch that seems to avoid the problem. Searching the forum, I was surprised that I didn't find any prior discussion of the problem, Comcast being fairly common. Is it worth submitting an issue against the Arduino repo?

@@ -48,11 +48,11 @@ int EthernetClient::connect(IPAddress ip, uint16_t port) {
   }
 
   if (_sock == MAX_SOCK_NUM)
     return 0;
 
-  _srcport++;
+  if (++_srcport == 1080) ++_srcport;         //comcast blocks port 1080 inbound, so skip it
   if (_srcport == 0) _srcport = 1024;
   socket(_sock, SnMR::TCP, _srcport, 0);
 
   if (!::connect(_sock, rawIPAddress(ip), port)) {
     _sock = MAX_SOCK_NUM;

I do not prefer this kind of patches (hard coded) in Arduino core code.
There might be more ports to skip in the future and that would add up to a "black list" of ports to skip. making the code slower and bigger and ....

A more robust solution could be to change this single try in a loop that finds the first free non blocked port.

  _srcport++;
  if (_srcport == 0) _srcport = 1024;
  socket(_sock, SnMR::TCP, _srcport, 0);

  if (!::connect(_sock, rawIPAddress(ip), port)) {
    _sock = MAX_SOCK_NUM;
    return 0;
  }
  bool port_not_found = false;
  int old_port = _srcport;
  while (port_not_found)
  {
    _srcport++;
    if (_srcport == 0) _srcport = 1024;
    socket(_sock, SnMR::TCP, _srcport, 0);
    port_not_found = ::connect(_sock, rawIPAddress(ip), port));

    if (src_port == old_port) 
    {
      _sock = MAX_SOCK_NUM;
      return 0;
    }
  }

drawback is that it might try 60K ports ... but a simple counter could limit that to 5 or whatever...

does this make sense?

robtillaart:
I do not prefer this kind of patches (hard coded) in Arduino core code.
...
does this make sense?

Yes that does make sense Rob, thanks. Winced at it a bit myself, which is why I asked.

However, this is not a section of code I'd want to introduce that much overhead (or delay) into. Further, I'm not sure it's possible to positively identify a blocked port vs. some other issue (e.g. a bad IP address) in the code.

I only know enough to be dangerous with this stuff, but in debugging the problem, I came across the concept of "ephemeral ports". I wonder if using the range 49152 to 65535 would be better* than 1024 to 65535. Not sure whether there's any downside to rotating through "only" ~16,000 ports vs. ~64,000.

  • less likely to be blocked by ISPs, etc.

PS: A patch to use the ephemeral port range:

------------------------------ EthernetClient.cpp ------------------------------
@@ -12,7 +12,7 @@ extern "C" {
 #include "EthernetServer.h"
 #include "Dns.h"
 
-uint16_t EthernetClient::_srcport = 1024;
+uint16_t EthernetClient::_srcport = 49152;      //use IANA recommended ephemeral port range
 
 EthernetClient::EthernetClient() : _sock(MAX_SOCK_NUM) {
 }
@@ -51,7 +51,7 @@ int EthernetClient::connect(IPAddress ip, uint16_t port) {
     return 0;
 
   _srcport++;
-  if (_srcport == 0) _srcport = 1024;
+  if (_srcport == 0) _srcport = 49152;
   socket(_sock, SnMR::TCP, _srcport, 0);
 
   if (!::connect(_sock, rawIPAddress(ip), port)) {

(just a thought) using port numbers above 32767 might reveal implementation defects :wink:

Maybe the best solution is to have a list of source ports in use?
NB if there is a port in use, and the algorithm has tried all number it will encounter a used one....and fail
skipping used port numbers is not that difficult.

your ephemeral port patch sounds reasonable in itself, but is no guarantee there will be no ports blocked in that range. So it does not make the algorithm more robust. The loop implementation I proposed can also be done by the developer on a higher level, calling connect until it connects.

BTW 16000 ports should be more than enough, given the Arduino can open only 4 sockets (IIRC) simultaneously.

robtillaart:
(just a thought) using port numbers above 32767 might reveal implementation defects :wink:

Being just a subset of what the current code uses, not sure I'd expect any additional trouble.

your ephemeral port patch sounds reasonable in itself, but is no guarantee there will be no ports blocked in that range. So it does not make the algorithm more robust.

Agree no guarantee, but it may in fact be more robust as the 49152–65535 range is recommended by IANA. The history of what ranges various OS and versions have used is interesting in that it's quite varied. Recent versions of Windows use the IANA range. (This suggests a new slogan, "Arduino: No worse than Windows!" :wink: )

Well maybe that last isn't such a good idea. At any rate, I've begun testing with the IANA suggested range. My one logger will take a little over 11 days to cycle through the 16K port numbers, another logger will only take a little over two days.

I recently switched to Comcast internet, and it works fine, but my Arduino IoT loggers started to experience occasional connect failures when sending data to online database services. After a week of spinning wheels, jumping to bad conclusions, barking up wrong trees, and not recognizing evidence that pointed to the actual problem, I finally realized that Comcast blocks inbound traffic on port 1080.

So what did Comcast say when you asked them about this issue?

Nice call, zoomkat! They would say this:
http://customer.comcast.com/help-and-support/internet/list-of-blocked-ports/

Port 1080 is vulnerable to, among others, viruses, worms and DoS attacks.

Just curious, what makes port 1080 more of an issue than other ports, and why would somebody specifically want to use port 1080?

zoomkat:

Port 1080 is vulnerable to, among others, viruses, worms and DoS attacks.

Just curious, what makes port 1080 more of an issue than other ports, and why would somebody specifically want to use port 1080?

Probably not the port per se, but maybe because some program that used or uses it had vulnerabilities. I see that 1080 is an officially assigned port for SOCKS proxy, but I'm not up on that or whether there are associated risks.

from - UDP 1080 - Port Protocol Information and Warning! -
PORT 1080 – Information
Port Number: 1080
TCP / UDP: UDP
Delivery: No
Protocol / Name: socks
Port Description: SOCKS. SOCKS port, used to support outbound tcp services (FTP, HTTP, etc). Vulnerable similar to FTP Bounce, in that attacker can connect to this port and \bounce\ out to another internal host. Done to either reach a protected internal host or mask true source of attack. Listen for connection attempts to this port — good sign of port scans, SOCKS-probes, or bounce attacks. Also a means to access restricted resources. Example: Bouncing off a MILNET gateway SOCKS port allows attacker to access web sites, etc. that were restricted only to.mil domain hosts.

zoomkat:
Just curious, what makes port 1080 more of an issue than other ports, and why would somebody specifically want to use port 1080?

1080 has (historically) been the target of several exploits.

During the 1990s, a NAT and proxy server called WinGate, was shipped in a default 'open' configuration. Ease of use and a free version, made it a popular choice of inexperienced and part time network admins, lacking the expertise to lock it down. The developers cottoned on and secured the default configuration but not before the hackers had learnt there were a mass of Windows 95, 98, NT and 2000 servers they could bounce their attacks off.

Later when XP was released, 1080 was used by the WinHole exploit kit which, like so many other XP trojans, was prevalent prior to the introduction of XP SP2. WinHole facilitated the distribution and control of spam bots, which would have cost Comcast a lot of bandwidth. I am not very familiar with the ISP market in the US but am lead to understand, Comcast is/was a popular choice amongst less technically adept customers - A bit like BT over here.

No I don't think so, for several reasons;

  1. Port blocking is firewall functionality (application layer) rather than interface functionality (below layer 5). A network device on a LAN should not be blocking any ports, in my humble opinion.
  2. ISP specific. Comcast are one ISP in once country. There are other countries with dominant ISPs blocking different ports.
  3. Comcast don't only block 1080. Apply the same logic to the other ports they are blocking and you cut off some very important services.

Adopting the IANA ephemeral port range might have legs. Personally, I just prefer not trying to save people from themselves all the time. The lesson here should be to isolate the fault as occurring on the WAN and check your ISP is not blocking ports, right after checking your own firewall is not blocking ports.

MattS-UK:
1080 has (historically) been the target of several exploits.

Thanks for the background!

  1. Comcast don't only block 1080. Apply the same logic to the other ports they are blocking and you cut off some very important services.

But it is the only port they block in the range 1024-65535 currently used by the Ethernet library. Avoiding use of blocked ports does not cut off any services as the change is only to the port range used by Ethernet client when selecting a source port for outbound traffic.

Adopting the IANA ephemeral port range might have legs.

Agree. I've made that change and am currently testing. All is well so far and I don't expect any issues. I've also submitted a pull request to Arduino to use the 49152-65535 ephemeral range. That way it is not ISP-specific and I think that ISPs will be very unlikely to block ports in that range.