 thanks for joining and listening to me. So I will talk about my site project. It's more an experiment and I have to say it is not an OpenBSD project, right? Some people ask me about OpenBSD from time to time. I'm not actively working on OpenBSD right now. So this is just my own little site project. So I'm working professionally with Rust for years, maybe a little bit longer now. So I initially had my love-hate relationship with the language, but meanwhile I don't really want to work on C anymore. So that was one reason why I got a little bit tired of working on the C code and OpenBSD and didn't contribute much in the area anymore. So then I wanted to write something new. So I went to ReLady and how could I possibly rewrite ReLady from C to Rust? So a quick overview. I give a short history from ReLady. I mean it's around 14 years old now. So that's quite some time already. And then I will give an overview of my Rust ReLady work and the current status here and how we can potentially get it done. So this is a very old picture I had in an old presentation as well. That was Eric and me. We kind of started ReLady. I merged in part of this code into my proof of concept at the time. And this was a hackathon in Ito in 2008. So 2006 I started it. Then it had this famous history of being renamed a few times, host state D to host state D and then later ReLady. The renaming happened at OpenCon actually in Italy. And yeah, it's still in use. Many years later, even without me, people are still actively maintaining it and OpenBSD and Beno, Claudio and many people have done some improvements there. So yeah, I'm very thankful for that. Basic features of ReLady. It started as a load balancer and link balancing features, supports various health checks. And that's important for the Rust re-implementation later. It has four components of like layer three redirects. So that's how it started to do health checks and dynamically program PF tables so that the PF-RDR as redirection targets depend on the ReLady health checks. I later added the layer seven mode relays that allows to do TCP relaying header manipulation and so on. That's the old proof set up. So ReLady from the beginning was designed in a way that it runs with multiple processes and those processes use IMS to communicate with you. The term was coined by Henning, but it's used everywhere in OpenBSD. And yeah, it's a simple internal HPC-like protocol over socket pairs and processes. And yeah, ReLady does not implement any threading or so on. It's in the layer seven mode. It just forks a number of worker processes and each of those processes is using LibEvent and the AsyncIO that it implements. So much about the past. Now about Rust and ReLady. So in 2019 I had some time and then I started working on HTTP to support for ReLady. And I actually made some pretty good progress. I had like basic HTTP to core engine. I had the HPEC protocol. It was all written in C. And I actually talked about it at EuroBSDCon. And there I jokingly mentioned that I could as a future step rewrite ReLady that are ReLady and Rust. But many things changed. They are the pandemic hit. And during this time I lost interest in C. And I don't know. Everyone had probably a situation where you really had to realign a little bit. And I focused on my work project. And there we had a very interesting project at Kraken where we introduced a new RPC gateway where like all the requests that are on the platform coming in are handled. And we wrote this in Rust, in AsyncRust, in Tokyo. And it's just amazing how fast this is and how low the latency is. So it just inspired me to have a look at ReLady and see, okay, how can we first implement ReLady in Rust and then later see how we can benefit from all those additional performance improvements that we have with like the Async thread pool and so on. So kind of like bringing those two worlds together. So the design costs are initially to have compatibility with the OpenBSD ReLady. I mean, that is probably necessary. And people ask me why adding this complexity. But for example, I'm not using a Tommel configuration file or YAML or whatever it's modernized right now. I want to be able to pass a ReLady Conf file and run with it. Another important thing that I utilize Rust, the AsyncRust, it's stable since late 2019. We have this native AsyncRust in Tokyo.io is basically the Async runtime. It can be compared to libend if we do a far stretch in C. The concepts are totally different, but that's basically the library that is very good for AsyncRust. So my roadmap is to start with the privilege separation part because I think it's a common problem with Rust services. I hear it all the time. I work with many very good Rust engineers. But I hear at many times that people don't have enough trust on the language and say, okay, the language is secure and then that's about it. But you have to do a lot more to keep Rust secure. And one concept is that those FAT binaries that are very common. You compile your service, you have one binary, one process, a single process, and then all the protection that you get is maybe a Docker container. That is something that I don't want to do. I want to keep privilege separation. I want to have multiple processes for isolated tasks. I actually want to have a Unix-style DMA, not just a Docker process. So the goal is to have privilege separation in Rust as we are doing it in C. So this was my focus. As I said, mostly a site project. So I didn't move on so quickly here. But this is done. The next thing is to have what we call DEMAN, like the RelayD CoreSource code. There is a configuration parsing and then it goes into the details. The first thing that I released is when you do Rust development, then you have to release some Rust traits. Is it a good thing? I don't know. But that's what I released. The privilege is my code base where I implement the DEMAN framework, the privilege, the async logging, but in a style that is not quite OpenBSD.c, but coming close. So it can actually do syslog when you run it in a background, standard error logging when you do it in a foreground. Syslog support these days is very really poor because most people just log to foreground. So yeah, I use it here because I want to keep this and I want to be able to run this in a round as a DEMAN, but you can also run it in a foreground and log to standard error. So looking at the Rust code, there are some source files right now. You have a configuration, you have the different, yeah, in OpenBSD RelayD, we call that the engines. So the engines are the different processes. We have the parent process, the health, the redirection is what paid later, and Layer 7 Relay. You can configure this here that already works with the Prusa trade in such a Rust enum where you use PROC macros to decode the config. This can be compared a little bit with those tables that we have in most Prusa DEMAN where you define the relation between the different processes. The configuration is generated in this one macro and it uses the, when you define health here, then it uses the module health, RS, or however you define the module, and calls the main function in there. So all this is done and Prusa RS create, you create a bunch of stub files, you have this core definition, and your parent holds and does all the file descriptor passing of the soccer communications and all that. Here is even a feature where I connect the processes redirect and relay with the health engine that's like that relay does it, right? The health engine does the health checks and then it sends messages to the other processes that the host is down or up. And this attribute here, I can configure that they're connected to each other and can talk with each other. The configuration style is a problem, actually, because as I said before, like most modern software is using kind of like a standard language, YAML or Tommel, whatever, even GISN, but I didn't want to do that, right? So the YAML and Tommel can be parsed and in Rust very easily, we use a 30 create where you basically just define different struct, makes them serializable, and Rust, the different backend library makes a work for you. So you just specify the types and you can convert it to YAML or Tommel and back. This is actually very convenient, but in a case of like a relay decon from the parse.Y style, it's an actual grammar. We need a parser that knows the syntax and so on. So I decided to use NOM for that. That's a very popular parser in Rust or it's actually a parser combinator. So it's not the act where you have a BNF style or all that. Your parsers actually, you declare it with Rust functions that call each other. So there's a fraction from the config parser, but basically you can define, that's actually enum, not num, but that's a typo. You define an enum, for example, with your different functions that you have in the DEMON configuration file and those are the return values. And then you can write functions that use the num library to do the matching. So here the section, basically the core entry point where it checks the different keywords, the interval itself is a function that checks the interval keyword and then the syntax there, the time that we have specified there. So it parses it and then it turns a new section data that eventually it's actually a really nice way to write a parser by just by declaring those functions. Old versions of NOM used Rust macros are quite ugly, I think. I don't really like working with Rust macros, but with the new version you can just use this function style and create your parser combinator with a native Rust syntax. The health service is actually something that is relatively easy in Rust compared to C because the health checks can now run in parallel. All the framework to set up TCP connection, ICMP and so on is easier and we have ASUN DNS. We have all those things that took us a long time to get there and see in Rust already. That's the easiest service part that can be implemented here. So the design of the health check engine is still the same and it runs in an interval of by default every 10 seconds. It runs all the tests and then for each host in each table it tracks the starters of the whole up or down. Indifference to C and that's an old bug that these real ideas like obviously it's just like linear. It's going through all the hosts within those 10 seconds and it can happen when you have many hosts even if you're using ASUN but then run concurrently and not in parallel. So when you have many hosts it can happen that one host gets scheduled so late in the cycle that it runs into this hard 10 seconds time or even if the check was five basically and with ASUN Rust it's not the problem anymore here. Why? Because Tokyo implements a multi-threaded scheduler so every ASUN scheduler you have can run on different threads and Tokyo itself is managing this transparent with a thread stealing approach. So this is a reason when you look at the old table where I had multiple relay processes that I decided okay I just need one relay process. There's no security benefit or whatever benefit of having multiple processes but now the single relay process uses a Tokyo thread pool so I can handle my connections in parallel. The nice thing is threading in Rust is actually one of the strengths because all the concepts of the language make it really hard to run into the same problems that you have and see. So locking is nice because when you acquire a lock it automatically runs out of contact when you leave the block. You never have to care about unlocking. Then Rust has built in thread safety mechanisms like the send and sync trades and so on. So it cannot fully prevent race condition. It's still possible by logical errors but one of the core strengths of Rust and ASUN Rust is that you can build ASUN threaded programs very easily and they scale very well. So that's why I decided okay I only want one relay process. And that's mostly the current situation. As I said I'm but slowly so I'm currently working on the health check engine and more of the configuration grammar. The next is not relay but relay so I want to start with the TCP redirections, TLS and so on. TF integration is going to be a challenge because it is possible of course but doing IOC TLS from Rust means that you have to write a lot of unsafe code. So unsafe code is what Rust calls directly accesses pointers, raw memory and so on and so you IOC TLS is one of the worst examples. It's certainly possible but it is not really nice to do it in Rust and that's by design. There is a public library to access PF from Rust, the dev-pf interface but yeah that is more for macOS and I'm not sure if I want to do that. So this is something I moved back and right now it doesn't support a control socket. The control socket like the relay CTL first it's quite optional and then the second thing it's not too difficult it's just not my my priority right now. The other thing about this is that this relay ID can easily work on OpenBSD that's where I do my main development but also on macOS and maybe even Linux just for Linux. I don't know that the redirects will probably just not be supported and maybe later somebody comes up and to the implements whatever Linux does but that's not my goal but I want to be able to use it on macOS or DSDs and OpenBSD. So so much about the slides. There are more things to mention is FIDIScript or passing is a feature that I implement in the Prifcept RS crate but it's also in the Rust core line not the whole Prifcept thing but just the ability to do the C message style FIDIScript or passing. That is in the Rust nightly version and will hopefully be available in one of the future releases just makes it easy to remove a little bit from the from the Prifcept RS crate and and then have like one maintain standard way to do those messages with ancillary data. I didn't write that I was involved there and I fixed it on OpenBSD and macOS and they merged by patch so there's a chance that we will get this. So now I hope that you still see me. Okay, can you see me? Hear me? You don't have to see my face but so questions. Where can we find the source code? So the source code is right now as I said like on crates.io and on github. Yeah, I'm using github actually and the relady source code is also on github but I think it's still private but I will make it public in the next days. It's still fairly early but I'm definitely moving forward now. Actually I have my motivation that maybe one day to replace some whatever hx or something like this with that so but right now as I said it's mostly a side project. Let me... Where is your code? Okay, yeah, it's definitely going to be open source. No worries. It's all just... So you can still hear me. I cannot say much about the tooling on on BSD but I know on BSD there is very good support for Rust. Samaria is doing a great job to get it into OpenBSD and there is some work as I heard that people are experimenting with like writing Rust based things like that but none of this is officially supported right now. I don't think that once Rust and OpenBSD yet. Yeah, so for me it's real idea because I have the experience with running this high performance gateway at Krak and I know I have a good feeling there what needs to be done and I always need a connection to my interest to the production news eventually but I don't know I mean what would be interesting for other people? Core utilities, would it be worse rewriting LS and all that? I mean the OpenBSD based utilities are pretty good and they have pledge and everything so we don't really have to rewrite every just for the sake of rewriting it. So I would say anything that is somehow performance-bound Rust is making it so better as we finally can safely use async and threading there. Okay, anything else? I heard we're running out of time. Limitation? Okay, one run. This is with some ugly debug message in between with the health check engine I'm working on right now. Thank you everyone.