Hi Guys
Wondering you can help us out with an interesting problem. I help run the network for several large UK LAN parties, and this weekend I was trying to get our Factorio server to show up in the lan browser (connecting via hostname is flawless as an aside). Due to the nature of our LAN setup we have multiple VLANs for different clients and the servers, so whilst a client could exist in 10.10.60.x or 10.10.20.x the factorio server exists in the 10.20.10.x range.
From looking in depth at the factorio browser handshake it appears to do the following
* Server broadcasts to .255 on 34196
* Upon recieving a broadcast from 34196 the client connects to the server to query on port 34197
* The server then responds (presumably with a simple acknowledgement)
This works flawlessly within a subnet, however we are suffering from some issues with the cross vlan setup. We use a udp forwarder to forward specific UDP broadcasts between the different subnets and have included the 34196 broadcast from the factorio server I having done some wiresharking I can see this broadcast appearing in the client vlans (as expected, a broadcast from 10.10.20.9 --> 10.10.60.255) however, the factorio client appears to ignore this. I've done a significant ammount of diagnostic on our end and as far as I can tell there is no issue on our network.
Having done some searching the only thing I can think of is that the factorio client does a check upon receiving the broadcast to determine if it's actually originating from the local subnet, however I believe this to be wrong as if the broadcast is received and the handshake connects successfully then I see no reason why the factorio client shouldn't treat the server as acceptable/accessible
Anyone (preferably a dev ;P) got any experience / thoughts on this?
Multiplayer LAN Server Discovery accross VLAN boundaries
Re: Multiplayer LAN Server Discovery accross VLAN boundaries
Hello,
I think firstly it should work. But are your server authentifcated on factorio.com because maybe it stays blocked on this lan because of this.
I know that if you don't have authentficated your server on the factorio network you only see it in your local area and not on other vlans.
Also in the factorio server-settigns.json one time you logged in your account select only visible in LAN.
Maybe it helps
Poli
I think firstly it should work. But are your server authentifcated on factorio.com because maybe it stays blocked on this lan because of this.
I know that if you don't have authentficated your server on the factorio network you only see it in your local area and not on other vlans.
Also in the factorio server-settigns.json one time you logged in your account select only visible in LAN.
Maybe it helps
Poli
Re: Multiplayer LAN Server Discovery accross VLAN boundaries
Hey VibroAxe,
Did you ever find a solution to this? I'm also curious as to what UDP forwarder you're using.
I've got a similar situation (much smaller scale but VLAN/router boundaries are still the issue) and I'd like to know how you solved it as your solution should work for me as well.
Thanks,
Meep
Did you ever find a solution to this? I'm also curious as to what UDP forwarder you're using.
I've got a similar situation (much smaller scale but VLAN/router boundaries are still the issue) and I'd like to know how you solved it as your solution should work for me as well.
Thanks,
Meep
-
- Long Handed Inserter
- Posts: 82
- Joined: Sat Jul 08, 2017 6:26 pm
- Contact:
Re: Multiplayer LAN Server Discovery accross VLAN boundaries
Broadcast packages cant go through a router. Even if you are using the same switch on different VLAN you will have a routing problem (With different subnets).
An UDP broadcast forwarding should probably work (Similar as IP Helper), I have never tested but it should work. Can you provide running-config?
You should also include network masks
http://h22208.www2.hpe.com/eginfolib/ne ... 03s10.html
https://community.cisco.com/t5/switchin ... -p/1396999
An UDP broadcast forwarding should probably work (Similar as IP Helper), I have never tested but it should work. Can you provide running-config?
You should also include network masks
http://h22208.www2.hpe.com/eginfolib/ne ... 03s10.html
https://community.cisco.com/t5/switchin ... -p/1396999
Re: Multiplayer LAN Server Discovery accross VLAN boundaries
Not tested, but I would expect you could just to the connect to (internal) IP of the server.
Re: Multiplayer LAN Server Discovery accross VLAN boundaries
Hey Folks,
When I came across VibroAxe's post a few days ago (nevermind that he posted it 10 months ago) I wasn't expecting my post to act as a bump to his original thread. I simply wondered if he had a solution already and if he'd be willing to share it. However, I guess what is done is done and all I have left to say about it is "while all answers are replies, not all replies are answers" or helpful.
I'm going to start with one simple fact: I have a working prototype to exactly what is being looked for in this thread (keep reading).
Now onto the direct responses. How I did it will be further down.
Now onto how I did it. Gather around folks, this is going to be highly technical and not for the faint of heart. If you decide to be a naysayer, remember, I have this actually working.
I started with what VibroAxe had already discovered to give me a head start into how the local game browser worked so koodo's to him. Just to recap, the factorio server continually sends out a directed broadcast on port 34196 to the directly connected subnet. When the client is looking for local games, it is simply listening for these broadcasts on this port. When the client receives one the client connects back to the server's normal game port 34197 to query for additional information.
So starting with this, I decided to grab the actual packet and take it completely apart. This is the complete IP packet captured that was sent on my network (this is hex for those who don't know - each pair of characters is one byte meaning that the group of 4 are two bytes long):
Yes, that is the complete IPv4 packet with the UDP and Data payload. It really is that short.
To simply the explanation, let's break this down into groups of 2 (32 bits or 4 bytes) per line and give them line numbers for our discussion.
Okay, if we look up the structure of and IPv4 packet, we know the following about each line.
1) This contains the IP version number (4), the header length (5), the type of service (00), and total packet length (1F = 31 bytes)
2) A packet ID and some fragmentation flags.
3) The TTL (FF = 255 - how many layer 3 devices can it cross before being discarded), the fact the next part is UDP (11 = 17 which is the protocol number for UDP), and the IP header checksum.
4. The source address which in this case translates into the IP of my local server (C0 is 192, A8 is 168, etc until you get 192.168.222.48 which is the IP of the server)
5. The destination address which translates the same way but into 192.168.223.255.
That's the complete IPv4 portion of the packet. Now, this is not a local broadcast. since that would be FFFF FFFF or 255.255.255.255. No, this is a directed broadcast!!! It just happens to be to the local subnet. For those who have caught onto it being 223 instead of 222, that's just because I use a /23 subnet mask (if you don't understand what I just said, don't worry about it, it's unique to my setup and irrelevant to what we're talking about here).
Okay, now onto the UDP part
6. This translates into the source port (CAFF = 51967) and destination port (8594 = 34196) that is being used (notice the destination port - this is how we know what port it's being sent to for the clients).
7. The UDP length including the header (B = 11) and the UDP checksum. Keep in mind that the UDP header is 8 bytes itself (the length of lines 6 & 7).
Okay, that just leaves the data.
8. These 6 characters or 3 bytes worth is the complete data payload that is being sent.
Now there is something very interesting about this. The fact that the payload is only 3 bytes long but an IPv4 address is 4 bytes long, this tells us something VERY IMPORTANT!
Now it was almost a fluke that I discovered it, but if we took the data payload and reversed it by byte, it would flip to 0x85950F.
If we then take the first two bytes (8595) and translate them, we get 34197 which is the port that the server is running on. The final 0F I actually have no idea what it's for but I've also seen it send 2F. I'm guessing it's some extra info but the devs will have to tell us. It's also completely irrelevant to us.
Stop and think about that for a moment. The server application itself is only transmitting the Port number the server is running on and not the IP address of the server. It's leaving the source IP address of the server to be determined by the underlying OS and its network stack instead of including it in the data sent out to clients.
So what does the client do then? Well, it receives this broadcast packet, gets the port number from the packet, and the connects on that port back to the IP that sent the packet (the source IP on line 4).
Okay, this gives us some options (all of which work).
The first option is to write a script/program that runs on the Factorio server, watches for the broadcast packet from the server on port 34196, and then takes the three bytes of data and sends a DIRECTED BROADCAST to any subnet that it can reach (aka is configured for). This would effectively be announcing the server to another subnet but still have the factorio's server's IP since it's still coming from the same machine/IP as the factorio server. If you know the port beforehand, you could very easily just fake the packet and advertise a server that doesn't even exist. If you're in control of the network, you can configure the necessary firewalls to allow the broadcast to happen.
The second option is similar to the first but a little trickier. Instead of being on the factorio server, you can write a script that sits on any machine on the same subnet as the Factorio server. When this script sees the broadcast from the Factorio server it builds the same packet and transmits the same information but spoofs the source IP of the packet to look like it came from the Factorio server instead of whatever server it's running on. If you have a router in the middle of a network that can run such a script, it can be listening on all of the connected subnets and rebroadcast those packets to the other subnets while spoofing the source IP so that the clients know where to connect.
The most interesting part I found is when I tried this over an OpenVPN connection. I found that it actually works if I UNICAST (send to single machine instead of everyone) the packet instead of broadcast it. I found that the client still found the server in the local game browser.
This last part I found interesting. It really confirms that the client is doing nothing more then listening on a port and then connecting to the source IP of the announcement packet on the port given in the packet.
If anything, while VibroAxe hasn't responded (and I don't expect him to), my guess is that his helper was transmitting the packet using the helper's IP instead of keeping the IP of the originating factorio server. However, what he's said half contradicts this so he'll have to chime in with an actual answer on that front.
Anyway, I might clean up this script and post it for others to use. As it sits right now, this script could very easily cause a broadcast storm/loop and cause all kinds of problems which I don't want to be blamed for.
Meep.
When I came across VibroAxe's post a few days ago (nevermind that he posted it 10 months ago) I wasn't expecting my post to act as a bump to his original thread. I simply wondered if he had a solution already and if he'd be willing to share it. However, I guess what is done is done and all I have left to say about it is "while all answers are replies, not all replies are answers" or helpful.
I'm going to start with one simple fact: I have a working prototype to exactly what is being looked for in this thread (keep reading).
Now onto the direct responses. How I did it will be further down.
You're only half right. Local broadcast packet's don't go through routers (or any layer 3 device) but a special type of broadcast called a DIRECTED BROADCAST can go through routers if the security configuration of the device allows it. It's how DHCP Relays work. Most routers allow it. It's the security appliances (firewall, IPS, IDS, etc) that block them by default because it was used as an attack vector in the early days of the Internet. A quick Google search tells me it's called a Smirf attack these days but I'll leave it to you to research further. Either way, I'm sure you can relax the security posture in this type of device if you really want to do this. Either way, a directed broadcast is not stopped by a layer 3 device by way of a protocol limitation.Skeletpiece wrote: ↑Sun Dec 09, 2018 3:22 am Broadcast packages cant go through a router. Even if you are using the same switch on different VLAN you will have a routing problem (With different subnets).
VibroAxe clearly stated that he is already using an IP Helper (and I was curious which one he was using) to forward the broadcast packet onto the destination subnet (and that part he had/has working), the problem is that the Factorio Client isn't listening to it. As a side note, while I don't know what device VibroAxe is using, I'm running an OpenBSD box as the router/firewall in my network so there really isn't a kind of single running configuration like there would be on a Cisco, Nortel, or other similar device. While I know you're trying to be helpful in suggesting you review the configs for errors, no, you can't have them (at least not mine).Skeletpiece wrote: ↑Sun Dec 09, 2018 3:22 am An UDP broadcast forwarding should probably work (Similar as IP Helper), I have never tested but it should work. Can you provide running-config?
This is not the thread you are looking for. It was clearly stated that this is not the problem, nor was it the question being asked. Direct connection to the IP was already stated as working.
Now onto how I did it. Gather around folks, this is going to be highly technical and not for the faint of heart. If you decide to be a naysayer, remember, I have this actually working.
I started with what VibroAxe had already discovered to give me a head start into how the local game browser worked so koodo's to him. Just to recap, the factorio server continually sends out a directed broadcast on port 34196 to the directly connected subnet. When the client is looking for local games, it is simply listening for these broadcasts on this port. When the client receives one the client connects back to the server's normal game port 34197 to query for additional information.
So starting with this, I decided to grab the actual packet and take it completely apart. This is the complete IP packet captured that was sent on my network (this is hex for those who don't know - each pair of characters is one byte meaning that the group of 4 are two bytes long):
Code: Select all
4500 001f a165 4000 ff11 9ae6 c0a8 de30 c0a8 dfff caff 8594 000b db2c 0f95 85
To simply the explanation, let's break this down into groups of 2 (32 bits or 4 bytes) per line and give them line numbers for our discussion.
Code: Select all
1. 4500 001F
2: A165 4000
3: FF11 9AE6
4: C0A8 DE30
5: C0A8 DFFF
6: CAFF 8594
7: 000B DB2C
8: 0F95 85
1) This contains the IP version number (4), the header length (5), the type of service (00), and total packet length (1F = 31 bytes)
2) A packet ID and some fragmentation flags.
3) The TTL (FF = 255 - how many layer 3 devices can it cross before being discarded), the fact the next part is UDP (11 = 17 which is the protocol number for UDP), and the IP header checksum.
4. The source address which in this case translates into the IP of my local server (C0 is 192, A8 is 168, etc until you get 192.168.222.48 which is the IP of the server)
5. The destination address which translates the same way but into 192.168.223.255.
That's the complete IPv4 portion of the packet. Now, this is not a local broadcast. since that would be FFFF FFFF or 255.255.255.255. No, this is a directed broadcast!!! It just happens to be to the local subnet. For those who have caught onto it being 223 instead of 222, that's just because I use a /23 subnet mask (if you don't understand what I just said, don't worry about it, it's unique to my setup and irrelevant to what we're talking about here).
Okay, now onto the UDP part
6. This translates into the source port (CAFF = 51967) and destination port (8594 = 34196) that is being used (notice the destination port - this is how we know what port it's being sent to for the clients).
7. The UDP length including the header (B = 11) and the UDP checksum. Keep in mind that the UDP header is 8 bytes itself (the length of lines 6 & 7).
Okay, that just leaves the data.
8. These 6 characters or 3 bytes worth is the complete data payload that is being sent.
Now there is something very interesting about this. The fact that the payload is only 3 bytes long but an IPv4 address is 4 bytes long, this tells us something VERY IMPORTANT!
Now it was almost a fluke that I discovered it, but if we took the data payload and reversed it by byte, it would flip to 0x85950F.
If we then take the first two bytes (8595) and translate them, we get 34197 which is the port that the server is running on. The final 0F I actually have no idea what it's for but I've also seen it send 2F. I'm guessing it's some extra info but the devs will have to tell us. It's also completely irrelevant to us.
Stop and think about that for a moment. The server application itself is only transmitting the Port number the server is running on and not the IP address of the server. It's leaving the source IP address of the server to be determined by the underlying OS and its network stack instead of including it in the data sent out to clients.
So what does the client do then? Well, it receives this broadcast packet, gets the port number from the packet, and the connects on that port back to the IP that sent the packet (the source IP on line 4).
Okay, this gives us some options (all of which work).
The first option is to write a script/program that runs on the Factorio server, watches for the broadcast packet from the server on port 34196, and then takes the three bytes of data and sends a DIRECTED BROADCAST to any subnet that it can reach (aka is configured for). This would effectively be announcing the server to another subnet but still have the factorio's server's IP since it's still coming from the same machine/IP as the factorio server. If you know the port beforehand, you could very easily just fake the packet and advertise a server that doesn't even exist. If you're in control of the network, you can configure the necessary firewalls to allow the broadcast to happen.
The second option is similar to the first but a little trickier. Instead of being on the factorio server, you can write a script that sits on any machine on the same subnet as the Factorio server. When this script sees the broadcast from the Factorio server it builds the same packet and transmits the same information but spoofs the source IP of the packet to look like it came from the Factorio server instead of whatever server it's running on. If you have a router in the middle of a network that can run such a script, it can be listening on all of the connected subnets and rebroadcast those packets to the other subnets while spoofing the source IP so that the clients know where to connect.
The most interesting part I found is when I tried this over an OpenVPN connection. I found that it actually works if I UNICAST (send to single machine instead of everyone) the packet instead of broadcast it. I found that the client still found the server in the local game browser.
This last part I found interesting. It really confirms that the client is doing nothing more then listening on a port and then connecting to the source IP of the announcement packet on the port given in the packet.
If anything, while VibroAxe hasn't responded (and I don't expect him to), my guess is that his helper was transmitting the packet using the helper's IP instead of keeping the IP of the originating factorio server. However, what he's said half contradicts this so he'll have to chime in with an actual answer on that front.
Anyway, I might clean up this script and post it for others to use. As it sits right now, this script could very easily cause a broadcast storm/loop and cause all kinds of problems which I don't want to be blamed for.
Meep.
Re: Multiplayer LAN Server Discovery accross VLAN boundaries
I have finally cleaned up and performed some final checks to the scripts that perform the actions necessary to send a broadcast to subnets outside the current subnet.
I have posted the scripts to GItLab for all to see. If you find any errors, feel free to submit a pull request.
https://gitlab.com/meeper/factorio-lan-game-announcer
I have posted the scripts to GItLab for all to see. If you find any errors, feel free to submit a pull request.
https://gitlab.com/meeper/factorio-lan-game-announcer