There is nothing required to deploy in order to use Parsec out-of-the-box as all of the required infrastructure for ultra low-latency, high-performance remote access is hosted and managed by Parsec. Simply put, you just need the Parsec app installed on your existing computer(s), and you're ready to go. By default, the Parsec app leverages UPnP to establish a peer-to-peer (P2P) session between a client and host computer. However, as UPnP is generally frowned upon outside the context of a typical home network, we also offer several different ways for a client and host to establish a session between one another while keeping security and performance top of mind.
In this article we'll focus on the various connection methods, components involved, and network considerations when working, or gaming, with Parsec. This article assumes you have basic knowledge of TCP/IP, although some basics will be rehashed here.
Client vs. Host
Let's go ahead and get this out of the way. What is a client? By its definition in computing, "a client is a piece of computer hardware or software that accesses a service made available by a server as part of the client-server model of computer networks." For all intents and purposes, 'server' will be referred to as a 'host' in the context of Parsec. So what is a server? By its definition in computing, "a server is a piece of computer hardware or software that provides functionality for other programs or devices, called clients".
Okay, let's paint a picture... A picture involving gaming (lets face it, we all love to game). You've got that sweet new Atari, Nintendo, Playstation, Xbox, or whatever the sweet new system is or was for your generation (Game Gear anyone?). Now, you're the only one in the neighborhood with this cool new toy, and all of your friends are super excited to come over to spend time with you and play games on your cool new system- great! So, your friends ask to come over to your place, to which you oblige. These people are guests in your (or your parent's, heh) home, there to play games with you - the "service" you provide.
In other words, these people are clients. As these people are guests in your home, you are hosting these folks and providing them the ability to play your cool new gaming system. This makes you the "server", or in other words, the host. Translating this to a Parsec session, the computer running the game or desktop session is the host. The computer connecting to the host, for control of the game or desktop, is the client.
Firewall, UPnP, hole punching and NAT
Continuing with definitions from Wikipedia, a firewall is "a network security system that monitors and controls incoming and outgoing network traffic based on predetermined security rules." There are many forms and flavors of firewalls, but we'll keep things simple. Let's go back to our previous example- we've got friends that want to come over to your house to play games. The security components of your home will be considered our "firewall": cameras and sensors, door locks, window locks, alarm system, etc. Let's say that everything is locked down so nobody can get in, which is the ideal default configuration of a firewall. How do our friends get into our house to play games, or in the context of Parsec, how does a client connect to a host? Well, we have some options:
The default method leverages UPnP (Universal Plug and Play) and hole punching. You may already be familiar with these terms if you've ever had issues using a console to connect to online gaming services from a home network where UPnP is disabled, as most consoles leverage UPnP to automatically configure your router for multiplayer services (gaming, chat). The game console, or in our case Parsec app, sends a request to the upstream router/firewall to automatically configure port mapping for NAT traversal - in simple terms, it creates a rule to allow external traffic that hits the NAT gateway on a certain port to get passed through to an internal address and port. In the context of Parsec, the external address is the client and the internal address is the host. Additionally, the destination port, or Host Start Port, is selected at random by default. If UPnP is enabled and functioning properly, or UDP hole punching (leverages STUN) is successful, Parsec will work out-of-the-box. When the session is killed, the rule should be removed and port closed, blocking subsequent inbound external traffic over the port that was previously opened.
Let's go back to our scenario where we have people who want to come over to your house to play games on your console. In essence, the UPnP equivalent here is you pressing a button that automatically unlocks a random window in your house, and signaling to your friend that the window is open for them to get in to the house. They come in, you play video games with each other, they leave, then the window locks automatically. If you're hosting multiple friends, multiple windows will be unlocked - one for each of them.
NAT, or network address translation, can be used in place of UPnP. While UPnP is enabled by default on most store-bought and ISP-provided home router/firewall/access point combos, it is often frowned upon due to a number of potential issues that are outside the scope of this document. For these reasons, UPnP is often times disabled on corporate networking gear - your workplace, for example.
Using a NAT-based configuration, the Parsec app on the host computer is configured with a static listener port. On the upstream router, a port-forwarding rule/DNAT rule is manually created to forward traffic from an/any external address and port through the NAT gateway, to the internal address and port that the host computer is listening on. In contrast to how NAT works relative to UPnP, the port-forwarding/DNAT rule persists even after the Parsec session is killed.
In some cases, configuring Parsec in NAT mode can be more reliable as rules are intentionally applied to forward Parsec-specific client traffic to a specified Parsec host. In other cases, NAT mode may be an explicit requirement as UPnP may be disabled on devices outside of your control, requiring you to specifically request that a port is forwarded to your host computer to allow Parsec. Again, this is common in corporate networks. While in other cases, you may have control over the upstream networking gear, at home for example, and decide that configuring port forwarding/DNAT is more appropriate (or your gear doesn't support UPnP).
If you're experiencing challenges with connectivity using the out-of-the-box configuration and you don't control the upstream networking gear, you'll need to reach out to your network engineer/team/NOC and ask them to create a port-forwarding/DNAT rule. It should be configured to forward traffic originating from external addresses with the destination port being the host computer's Start Port, to the local address and port of your host computer.
Please note that each concurrent session will consume one port in sequential order. If you plan to host 3 guests concurrently on the same computer, you will need to forward 3 ports to your host. If your Host Start Port is 8000, you need to forward port 8000-8002 to your host computer. If you add another computer, you will need to start at port 8003, and so on and so forth. UPnP mode behaves the exact same way but is handled automatically. We highly recommend assigning static IP addresses to Parsec hosts when configured in NAT mode.
Going back to our original scenario, let's say we can't just unlock the window(s) with a remote. Instead, house rules dictate that in order for someone to come in to the house, you must intentionally open a specific window for a specific guest and one for each concurrent guest, but those windows remain unlocked from that point forward. Because you don't have a remote to unlock windows as guests arrive, you'll be running around a lot to unlock another window for each guest- if you have 3 concurrent guests, you will need to open 3 windows. Also, there is a security guard at each window doing quick pat-downs to reduce the risk of unwanted, unknown, or malicious visitors.
Still with me? Don't worry, we're getting to Parsec specific stuff below.
Architecture and communication sequence
There are 4 primary components that make up the high level architecture of a Parsec environment.
- Clients
- Hosts
- Signal/Websocket API Gateway (Parsec hosted)
- STUN server (Parsec hosted)
We've covered the client and host, but what are the Signal API and STUN servers for? The STUN server is leveraged by both the client and host to discover their public connection information for UDP hole punching, in particular the public IP and source port that initiated the UDP conversation. The Signal API is also leveraged by both the client and host, so they can send messages in real time to one (no polling/requesting) another through their websocket connection to the Signal API. From a high level, the main piece of information the client and host send to one another through the Signal API is the connection information they discovered about themselves via a request to the STUN server.
The high level connection sequence of a typical Parsec session goes like this:
- Client starts a UDP conversation with STUN server on port 3478 to discover connection information.
- STUN server respond back with client's connection information - Client public IP and listener port - for NAT traversal.
- Client sends a message containing its connection information to the host, through the Signal API.
- Host starts a UDP conversation with STUN server on port 3478 to discover its own connection information
- STUN server responds back with the host's connection information - Host public IP and listener port - for NAT traversal.
- Host sends a message containing its connection information to the client, through the Signal API
- Now that the client and the host have each other's connection information (assuming they were both able to reach our STUN server) they both attempt to connect to each another at the same time.
- This is intentional and by design. The initialization of the connection depends on which connection attempt "wins", client to host, or host to client, based on time and/or success of NAT traversal.
Okay, step 7 is really confusing...Why would the host attempt to connect to the client? I've always been taught clients connect to hosts? Well, the answer is to increase the chance of successfully establishing a session. Let's say that the host is in UPnP mode on a network where UPnP is disabled unknowingly, and the client is also in UPnP mode on a network with UPnP enabled. Obviously the host won't be able to open a port for the client to connect through, but the client is. This effectively doubles our chances to establish a session successfully, ignoring all other variables. The idea is the same with NAT mode also - if a someone makes changes to NAT rules that block inbound traffic to a Parsec host, the host should still be able to establish the session through NAT traversal to the client, assuming no changes on the client side.
In an effort to try to keep this fun and educational, let's go back to our gamer friends scenario. Let's say your address often changes or you simply don't know it yet. Lucky for you, there's this device outside (STUN server), provided by a trusted vendor, that you can just ask. Now that you've got your address and window(s) unlocked you send your address and information about what window should be unlocked to your friend(s) as a message through the postal service (Signal API). Your friends did the same, just in case they're unable to get to your house or the window is locked because the remote (UPnP) failed to unlock the window. However no matter what, the game will be played at your house.
The ideal outcome is your friend receives your address and information about what window is open, they successfully reach your address and are able to enter through the unlocked window. Alternatively, your friend(s) get lost and goes back to their house to wait for you, so you need to go to their address and bring them back to yours through the window that's unlocked.