This is a side-effect of the fact that the OpenVPN 2 codebase is single-thread. That means it runs as a process on one CPU core and can’t make use of multiple CPU cores at once. To get around the obvious performance limitation this creates on a server with multiple CPU cores, we spawn multiple OpenVPN daemons on the Access Server. We spawn 1 TCP and 1 UDP daemon per CPU core by default. An internal simple load-balancing system using iptables connects VPN tunnel connection requests coming in to the least loaded OpenVPN daemon.
Each OpenVPN daemon needs it own network interface to communicate with the operating system. The Access Server makes sure people connected to 2 different OpenVPN daemons can still contact each other if that is necessary. All the communication simply passes through the operating system and hits the routing table which determines which interface traffic should go to. So this doesn’t cause a situation where clients are separated from each other when one is connected to one OpenVPN daemon, and the other to another OpenVPN daemon.
The interfaces looks like as0t0, as0t1, as0t2, as0t3, and so on, and each get a portion of the subnet defined in the settings in the Access Server.