ICE adapter status report 2

24

It's been almost a year since my last update.

Unfortunately apart from some initial progress with adding a web-based UI not much happened to the ICE adapter repo. I took multiple approaches to de-spaghetti the code, but still I couldn't even make sense of what I'm trying to change there. And everytime I tried to refactor something I ended up in modules that do not even belong there.

The lack of any kind of automated tests and the lack of the ability to run 2 ice adapters in parallel from the same IDE made it impossible for me to gain any progress.

So a month ago I started with a new approach. I tried to use the Ice4J library (the fundamental library that the ICE adapter is built around) in a standalone project and tried to figure out how to use it. Also ChatGPT was a big help, as it creates better docs than the original authors...

Starting from this and then decomposing the ice adapter classes I could iteratively figure out how the ice adapter actually works. So with each iteration I drew my learnings into a diagram until I had a good overview over how it actually works. This can be found here.

Based on these insights I started to slowly build up a brand new, cleaner implementation of the ice adapter in Kotlin. It's far from done yet, but it already has an integration test that connects 2 ice adapters locally, which proves me that this is possible.

The code was published today and can be found in this new repository.

The next step is to achieve functional parity with the java implementation. This might take a few more months though. So stay tuned for the update next year šŸ˜œ

"Nerds have a really complicated relationship with change: Change is awesome when WE'RE the ones doing it. As soon as change is coming from outside of us it becomes untrustworthy and it threatens what we think of is the familiar."
ā€“ Benno Rice

This slide deck is great! Always great to learn more about how this stuff works. One tiny mistake: On page 5 and 6 you have "wholepunching" instead of "holepunching".

Thanks for all the hard work!

I was curious what language you were using when you teased this on the other post. Happy to see it's not Java, but sad it's Kotlin as I don't know any Kotlin to be able to contribute lol

Either way I applaud the effort to rewrite the adapter!

So short update: Thanks to some help of BlackYps the basic functionality to replace a real ice adapter is in place and will be tested soon.

"Nerds have a really complicated relationship with change: Change is awesome when WE'RE the ones doing it. As soon as change is coming from outside of us it becomes untrustworthy and it threatens what we think of is the familiar."
ā€“ Benno Rice

@brutus5000 Is there any way someone with quite a bit of free time, a good bit of coding experience (admittedly not in Kotlin), and a willingness to do as told, might be useful to you?
Even if you just need tedious, repetitive tests running, I'd be so happy to help you with this.

I also had no previous experience in Kotlin and managed, so I'd say we can definitely use your help. You can take a look here, even though at the moment there isn't too much explanation of what needs to be done: https://github.com/FAForever/kotlin-ice-adapter/issues

Just a quick thought: Wouldn't it be easier to create a FAF VPN and pretend all players are in a LAN network? That architecture would solve a lot of problems at its core and simplify the connection chaos.

  • Putting a bunch of untrusted computers into a VPN is dangerous as it's no longer restricted to the FAF related ports.
  • we'd need to create one vpn per game. That's a lot of server coordination required and sounds more complex than ice
  • I see little reason why VPN should work if ice doesn't work

"Nerds have a really complicated relationship with change: Change is awesome when WE'RE the ones doing it. As soon as change is coming from outside of us it becomes untrustworthy and it threatens what we think of is the familiar."
ā€“ Benno Rice

10

Fortunately had some hours yesterday that I could spend. I fixed tons of issues in the client<->ice adapter communication and the connectivity check.

On joining a game with the new ice adapter hosted by a classic ice adapter, the classic ice adapter debug window shows a persistent connection that is kept being alive.
Unfortunately my game still does not join a lobby (stuck in joining lobby screen), so I guess there are some issues in the ice-adapter<->game connectivity that I need to figure out.

"Nerds have a really complicated relationship with change: Change is awesome when WE'RE the ones doing it. As soon as change is coming from outside of us it becomes untrustworthy and it threatens what we think of is the familiar."
ā€“ Benno Rice

I'm optimistic that the new version will continue to work for those of us that use IPv6. The current version does as it all uses IPv4 by default. I guess my comment is merely to make you mindful that we exist. It's actually the default in my country (Australia) on Telstra for example.

I'm happy to be a tester when it becomes available.

Former Board Member - March 2021 - March 2022

I don't want to crush your hopes but I haven't seen any code disabling ip v6 before and I didn't see anything to enable it either. So don't expect any improvements there.

"Nerds have a really complicated relationship with change: Change is awesome when WE'RE the ones doing it. As soon as change is coming from outside of us it becomes untrustworthy and it threatens what we think of is the familiar."
ā€“ Benno Rice

Does this option in the client just point to an empty hole then šŸ¤–
8f90580f-5a72-4311-aea7-fb729dc27400-image.png

Good question. Let me check this and I will post results here.

"Nerds have a really complicated relationship with change: Change is awesome when WE'RE the ones doing it. As soon as change is coming from outside of us it becomes untrustworthy and it threatens what we think of is the familiar."
ā€“ Benno Rice

I have not seen it in the ICE adapter because the client sets a JVM property that bypasses the ice adapter and directly affects the underlying ice4j library. By default ipv6 gets explicitly deactivated and only enabled if the set is activated in the client.

"Nerds have a really complicated relationship with change: Change is awesome when WE'RE the ones doing it. As soon as change is coming from outside of us it becomes untrustworthy and it threatens what we think of is the familiar."
ā€“ Benno Rice

@brutus5000 @clyf Well the last few games I played I didn't disable IPv6 on my PC and it worked fine. It was only a handful of games with one friend where I did that. It looks like everything is working the way it is meant to. Great news.

Former Board Member - March 2021 - March 2022

It works fine with IPv6 enabled (and always has in my experience), I think the question is does it work with IPv6 only? I know that's not a particularly common scenario at the moment but it could be in the future. Also with carrier-grade NAT could some people potentially see a better experience if it were to prefer IPv6?

If you have ipv6 only and the other side has -for some reason- ipv4 only, then it only works via relay. But in general it should work.

"Nerds have a really complicated relationship with change: Change is awesome when WE'RE the ones doing it. As soon as change is coming from outside of us it becomes untrustworthy and it threatens what we think of is the familiar."
ā€“ Benno Rice

10

1 hour ago we played a game with

ice-kotlin.png

Still lacking features like reconnect and telemetry though.

"Nerds have a really complicated relationship with change: Change is awesome when WE'RE the ones doing it. As soon as change is coming from outside of us it becomes untrustworthy and it threatens what we think of is the familiar."
ā€“ Benno Rice

Awesome!