I'd like to use Google App Engine to initiate http traffic to devices that will be behind firewalls/routers/NAT. These devices will be receiving commands from GAE. I could have the devices poll GAE looking for new messages, but this uses a lot of traffic. Alternately, I could try and hold open a connection permanently, but that is super expensive and bad.
The devices won't have static IP addresses. However, they will be communicating periodically with Google App Engine and the device can then listen to the port they just opened for any incoming communications. If I understand TCP Hole Punching since the devices already sent traffic to GAE they will have a port assigned that translates to the port the device is listening to and Correspondingly GAE have a hole available in the firewall.
However, in order for GAE to send traffic to the device it needs to know the device's assigned port on its public IP. Here in lies the problem, as GAE doesn't make available the source/remote port for incoming traffic. Without knowing the port the device just used, I can't send the device anything other than http response messages. I can't actually initiate http/tcp messages to that device.
So, does anyone know of a way of getting the incoming source/remote port for GAE or know of an alternate way of initiating traffic to devices behind firewalls?
TL;DR: How on earth do you get the remote port for http messages sent to apps on GAE?
Since the secure data connector is deprecated, your best option is to deploy a service that will proxy the incoming requests. You have a number of options like configuring your firewall and setup port forwarding or apache reverse proxy.
If your internal addresses change, then that is also the place to deal with this. For instance, you could let the DHCP server trigger a configuration change in your apache reverse proxy.
For future searchers, to follow up on koma's response here is the config for an nginx combination reverse proxy and forward proxy that should do the trick. The devices send all their traffic to it on port 80 which gets reverse proxied to App Engine. Oppositely App Engine sends requests to the firewalled devices using the forward proxy on port 8080 so that all GAE traffic appears to come from the same IP. The remote ip and remote port are added as headers of the proxied requests.
worker_processes 2;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
gzip on;
server {
listen 8080;
location / {
resolver 8.8.8.8;
proxy_pass http://$http_host$uri$is_args$args;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
server {
listen 80;
location / {
proxy_pass http://something.appspot.com;
proxy_redirect off;
proxy_buffering off;
proxy_set_header Host something.appspot.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-Port $remote_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}