Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bi-directional packet parsing #104

Open
Douile opened this issue Sep 24, 2023 · 2 comments
Open

Bi-directional packet parsing #104

Douile opened this issue Sep 24, 2023 · 2 comments
Labels
enhancement New feature or request v1.0.X Things about v1.0.X
Milestone

Comments

@Douile
Copy link
Collaborator

Douile commented Sep 24, 2023

I'm not sure this fits the goals for the project but I will put it here for comments.

What is this feature about?
Long term I think it would be nice to both serialize and de-serialize packets. As it currently stands we serialize requests in plain functions with no input data (in most cases), and de-serialize responses to a struct but in a standalone function. I imagine a nice abstraction would be like the serde Serialize, and Deserialize traits where both requests and responses can be created from Vec<u8> and serialized into Vec<u8>.

Use cases
This would enable people to use the library to create pseudo-game servers (I'm not suggesting we implement any of the server logic here). But this could be useful for testing: we could implement a pseudo-server and query ourselves using node-gamedig and rust-gamedig and compare outputs.

@Douile
Copy link
Collaborator Author

Douile commented Nov 30, 2023

I was implementing wireshark dissectors for game queries and I found this library: wsdf

It has a proc macro that allows parsing raw binary data:

#[derive(PacketField)]
struct ValveQuery {
  header: [u8; 4],
  kind: u8,
  challenge: Vec<u8>,
}

It then uses field annotations for more advanced decoding:

A decode function parses the data-type you specified into a different data type

#[wsdf(decode_with = "name_of_decode_function")]
kind: u8,

A consume function can consume an arbitrary amount of bytes from the buffer.

#[wsdf(consume_with = "consume_function")]
challenge: Vec<u8>,

There's also a neat attribute that allows you to chose the variant of an enum based on part of the previously parsed packet.

#[wsdf(dispatch_with = "kind")]
payload: PayloadEnum,

I think a similar design could definitely be used for gamedig, and it could make writing new protocols simpler.

It would definitely be a lot of work though especially with us needing to encode as well as decode types. And I'm not sure if there would be a performance detriment that makes this not worth it.

@CosminPerRam
Copy link
Member

Woah, that indeed looks great.
But sometimes when we decode a packet there are other conditional steps (e.g. additional data, stuff that needs to be mutated, decoding in another order etc) so I don't think we could apply something like this for all of our use cases (some yes but not all) but for sure it's something that might be worth to look into.

@cainthebest cainthebest mentioned this issue Jul 19, 2024
3 tasks
@cainthebest cainthebest linked a pull request Jul 19, 2024 that will close this issue
3 tasks
@cainthebest cainthebest added this to the v1.0.0-beta milestone Sep 30, 2024
@cainthebest cainthebest removed a link to a pull request Sep 30, 2024
3 tasks
@cainthebest cainthebest added the v1.0.X Things about v1.0.X label Sep 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request v1.0.X Things about v1.0.X
Projects
None yet
Development

No branches or pull requests

3 participants