Game Networking with Kubernetes/Agones - sockets

I am currently working on a multiplayer game that is meant to handle 20-50 player connections to a single game instance.
My current client connection model:
Client requests connection from server rest endpoint
Server creates 2 new sockets bound to random ports (1 tcp and 1 udp)
Client gets response and connects
I don't see anything glaringly wrong with this, but I am now questioning whether this is the general way that game server connections are done.
To explain further, I am in the process of learning how to use Kubernetes and Agones to deploy and manage app/game instances by wrapping them in Kubernetes pods. I am mostly working off of information found in the official guides (https://agones.dev/site/docs/getting-started/create-gameserver/) and associated github examples (https://github.com/googleforgames/agones/blob/release-1.15.0/examples).
For Agones, my understanding is that client connections are made via the port specified in "hostPort" in the "GameServer" yaml. I have previously deployed some instances with plain Kubernetes, using the "hostNetwork=true" option, which enables my above network model to work by allowing the game instance to bind directly to host ports and be exposed to the outside network. With Agones though, it seems that using this option is, at the very least, not encouraged (https://github.com/googleforgames/agones/issues/1389).
I'm certainly not an expert on networking, so please forgive my ignorance, but how are the client connections meant to be handled here if I'm only exposing one port? Is all the traffic multiplexed, or can I directly pass off connections somehow to other sockets/ports and have them automatically be exposed to the outside network?

Is all the traffic multiplexed, or can I directly pass off connections somehow to other sockets/ports and have them automatically be exposed to the outside network?
I would multiplex the traffic. It sounds like right now you are using the incoming port to determine "who is who". But you could also include that information in the packet flow to a shared port instead.

Related

Multiple clients - server chat application, multiple listeners on the same port are not allowed

Let's say I am creating a chat (client-server) application intended to use in my local network. I'm thinking about having a server which communicates with clients and multiple clients which communicate only with the server.
My initial thought was that the server is going to have TCP socket listener as well as each client. The problem arises when I have both the server side application and client side application on the same machine listening to the same port. This is not allowed. The same problem arises with two client side applications running on my computer which cannot both listen to the same TCP port.
How can I solve this problem? What is the common strategy?
The problem only exists if the client apps are binding to a specific port that the server app and/or other client apps are also binding to, instead of binding to ephemeral ports (which is the usual case for clients to do).
To bind to an ephemeral port, either don't bind at all (connect() does an implicit bind), or else bind to port 0 and let the OS pick an available port. In most cases, servers should bind to specific ports and clients should bind to ephemeral ports, when possible.
Your client apps do not need their own listening sockets to communicate with the server. They would need that only if they are performing things like peer-to-peer data transfers, etc. And even then, they should be using ephermeral ports, or pre-configured ports (in cases of firewalls, NATs, etc), and can use the server-based communications to share what those ports are with each other while negotiating the transfers.

How to find IP addresses of devices on local network which are running an instance of my app in Swift?

I'm working on a simple Swift app where one user can find other machines on a local network which are running an instance of my app and then send data to that machine using TCP sockets.
My question is how to find IP addresses of devices on same network which are running an instance of my app (cross-platform)?
I was thinking about listing all devices on local network and then
checking whether they have opened specific port (the port my app is
using)?
I also found that Apple provides service called Bonjour which could make my process discoverable. I'm not sure if this solution is good for cross-platform communication.
Apart of Mac-related stuff and high-level solutions (I believe keywords "network service discovery" will bring you to them), there are a couple of things that will work for a local network:
I Have a server that clients should report to. Some short hello-like UDP message and a timeout mechanism will be sufficient to keep a list of available clients in the network.
II Use IP or UDP multicast groups to notify others that a client has just connected to the network. Send a message to a multicast group and listen to this group to build a list of clients.
However, broadcasts and multicasts won't be transmitted through a router. So if your network is large enough only neighbouring clients will hear your notification. In order to overcome it,
III DHCP servers can be configured to provide custom data to clients via unassigned DHCP options. Large networks have usually such server. You probably can use it to send out a list of clients, but I'm not sure about this.

Can I write an OpenShift Origin app that can ingest UDP traffic on an external port?

How generic of a PaaS is OpenShift Origin? From looking at the architecture overview, it seems very web-centric. Can I use OpenShift Origin to build a private cloud where I can run arbitrary apps, not just web-based apps?
As the title of my post indicates, my pressing question is whether it is possible to create an OpenShift app that can open a socket and ingest UDP traffic -- I don't need (and don't want) an haproxy for this app, and I don't want all the UDP traffic to first go through the node host's proxy.
Essentially, I'd like to know if I can deploy an app to a node, and have that app be able to receive UDP packets from an external-facing port on that node. Is this possible?
The RedHat docs, Configuring the Port Proxy, make me think this isn't possible:
applications listen for connections on the loopback interface. The node runs a proxy that listens on external-facing ports and forwards incoming requests to the appropriate application
I'm hoping there is a way around this restriction. Would a custom cartridge work?
As far as I know thats not possible at this time. However I would suggest asking the developers for Openshift origin on either the mailing lists or you could check on #openshift-dev on freenode.

How to set up http server on iPhone behind firewall

I want to develop an iPhone app with a simple IM feature. I am thinking about setting up an HTTP server on an iPhone. If the iPhone is using wifi and is behind a firewall, how can I make sure that other iPhone clients can connect to it?
It's not the firewall that will disturb the connection as much it is the NAT.
When you are connected through wireless router to connect the internet you are surfing via NAT. it means you dont really have an extenral IP but once you initiate connection the router will map your intenral IP to one of his externatl ports and for certain time window he will pass connections to you if he will get it to the right port.
That being said, there is no actual way of setting a server behind a NAT unless you can configure port forwarding in the router and internal static IP.
Hope i was clear enough, good luck
I do not really think that you need to get an HTPP server up and running on iPhone to make an application that can send and receive messages (IM). The idea of making one iPhone user to directly connect to one another does not seem right to me since the users will need to know IP addresses of one another to do that.
Interconnectivity between different users of the chat can be solved by making your application communicate via a dedicated TCP port. It is generally advisable to choose ports with a number higher than 1024 since those below are generally found on the list of so-called well-known ports and are used for Web (like port 80), FTP (port 21), SSH (22), DNS (53), etc., it will be the responsibility of the user to make sure the port used by your application is open on the firewall. In order to solve this problem you can actually use port 80 for communication if you find that the port you have selected is blocked. You can do this because you know that this port will not be blocked in most cases. Indeed Yahoo Messenger is reported to use this technique when the firewall blocks the port it uses for communication.
The port should be used by your application to connect to the Web-server that will actually store user credentials, perform authentication, message transmission, etc., and the server should reside on capable hardware to be able to support large number of simultaneous connections. I can suggest using either a VPS (like the one provided by Linode) or a cloud (like Amazon EC2, Google Application Engine, Rackspace).

How to stop routers blocking traffic within a network?

I have an iPhone app which relies on connecting via the local network to a server running on a user's mac/pc.
The server is running an http service on port 8080
I already add exceptions to the default windows firewall, or the default mac firewall to ensure traffic is allowed to reach my app.
However the most common customer issue is that the iPhone can't communicate with the server.
Normally this is the network router blocking traffic - though sometimes the user is running their own firewall which blocks the traffic.
Is there a protocol which will let me say something to the effect of
'will all the firewalls on this network, please allow communication to <an ip> on <a port> if the traffic originates within this network?'
I have looked into upnp - but that seems to concentrate on opening a port to the outside world which I don't want to do.
suggestions?
thanks in advance.
No, there is no such way or protocol aside from UPnP. And I wouldn't recommend it anyway because in company networks it would cause all sorts of problems and security issues if this were possible.
I'd suggest that you set up a FAQ entry or installation section for your software where you describe this common issue and give details to the customers how they can detect and solve this problem.
In general, higher ports (above 8000 or 16000) are not blocked or firewalled. I would seriously consider allocating a random port in that range.
Also, consider to advertise your service with Bonjour. Using Bonjour has the nice side-effect that your iPhone app does not have to know the port number. It can simply browse the network for available servers. If there is just one then connect to that, otherwise present the user with a list to choose.
Is there any way to run the server on port 80? You're likely to encounter fewer issues on a standard port.