Skip to content

app-layer: websockets protocol support#10075

Closed
catenacyber wants to merge 1 commit into
OISF:masterfrom
catenacyber:websockets-2695-v6
Closed

app-layer: websockets protocol support#10075
catenacyber wants to merge 1 commit into
OISF:masterfrom
catenacyber:websockets-2695-v6

Conversation

@catenacyber
Copy link
Copy Markdown
Contributor

Link to redmine ticket:
https://redmine.openinfosecfoundation.org/issues/2695

Describe changes:

  • app-layer: websockets protocol support
  • rust : derive for protocol enumerations strings
SV_BRANCH=pr/1550

OISF/suricata-verify#1550 justrebased and force-pushed

#10074 with greener CI

Draft : what should be done for protocol detection ?
I hackingly register the probing parser on port 1

TODO:

  • Improve protocol detection hack
  • review all redmine ticket

Ticket: 2695

Introduces a device EnumStringU8 to ease the use of enumerations
in protocols : logging the string out of the u8,
and for detection, parsing the u8 out of the string
@codecov
Copy link
Copy Markdown

codecov Bot commented Dec 19, 2023

Codecov Report

Merging #10075 (160102e) into master (467c3f2) will decrease coverage by 0.05%.
The diff coverage is 86.48%.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #10075      +/-   ##
==========================================
- Coverage   82.39%   82.34%   -0.05%     
==========================================
  Files         972      978       +6     
  Lines      271406   271861     +455     
==========================================
+ Hits       223624   223864     +240     
- Misses      47782    47997     +215     
Flag Coverage Δ
fuzzcorpus 64.06% <51.93%> (-0.09%) ⬇️
suricata-verify 61.43% <84.33%> (+0.04%) ⬆️
unittests 62.77% <20.38%> (-0.07%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

@suricata-qa
Copy link
Copy Markdown

WARNING:

field baseline test %
SURI_TLPR1_stats_chk
.tcp.pseudo 2810 3014 107.26%

Pipeline 17144

if let Some(xorkey) = tx.pdu.mask {
js.set_uint("mask", xorkey.into())?;
}
if let Some(val) = web_socket_opcode_string(tx.pdu.opcode) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be more idiomatic if the derive was done as a From or FromStr implementation?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So rather ToString and FromStr ?
You are my reference for what is idiomatic in rust :-p

Is there a performance cost to do type conversion from integer to enum ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I misread this.. So it essentially goes from u8 -> WebSocketOpCode -> &str? My first feeling is the derive macro does seem like a little overkill since WebSocketOpcode doesn't seem to be used at all in the code, other than behind the derive macro? But that aside..

I think the derived code should implement a trait, or an impl block rather than a make function. Normally you might add a to_str() method...

impl WebSocketOpCode {
    fn to_str(&self) -> 'static &str {
        ...
    }

    // Or as a direct replacement.  Call like WebSocketOpcode::to_str()
    fn to_str() -> Option<&'static str> {
        
    }
}

Of course this assumes that you have a constructed WebSocketOpcode already, which it probably makes sense that tx.pdu.opcode might be an instance of, which could be done with an implementation of

impl From<u8> for WebSocketOpcode

I guess it feels odd that this enum exists only to generate some bare functions, but is never actually used?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So it essentially goes from u8 -> WebSocketOpCode -> &str?

Nope, not using WebSocketOpCode itself

the derive macro does seem like a little overkill

I want to code only once the match between integer value and string...
How do I achieve that without overkill ?
And without risking a typo if I code 2 functions (one stringer and one from str)

Of course this assumes that you have a constructed WebSocketOpcode already

I do not

which it probably makes sense that tx.pdu.opcode might be an instance of

It does not seem to fit for me asWebSocketOpcode enum has a limited number of values, and I still want opcode 3 that is unknown to be parsed...
Can/should I improve my enum ? Like adding a case Unknown(u8) ?

I guess it feels odd that this enum exists only to generate some bare functions, but is never actually used?

I agree.

Sum up :

  • Can/should I improve my enum ? Like adding a case Unknown(u8) ?
  • Is there a batter way than derive macro ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can/should I improve my enum ? Like adding a case Unknown(u8) ?

This makes sense.

Is there a batter way than derive macro ?

Implement the methods on the enum, like from_str and to_str?

This looks interesting as well: https://github.com/Peternator7/strum

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no standard to_str right ?

Should I use https://doc.rust-lang.org/std/string/trait.ToString.html ? That is to_string(&self) -> String so that allocates even if it is a static string... I think not

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no standard to_str right ?

Should I use https://doc.rust-lang.org/std/string/trait.ToString.html ? That is to_string(&self) -> String so that allocates even if it is a static string... I think not

No there isn't, but that doesn't mean you can implement it/derive it directly on the WebSocketOpCode.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strum does not seem to work for displaying the value of a case Unknown(u8)

cf code in https://docs.rs/strum_macros/0.25.3/strum_macros/derive.Display.html where Color::Blue(10) does only display blue without the 10

Ah, I didn't look at it that closely.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you not use strum for AppLayerEvent derive ?
Looks quite similar

Yeah, they do. derive(AppLayerEvent) was added to implement the AppLayerEvent trait we use in some generic functions and has some additional Suri only methods like get_event_info.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can check next version of the PR ;-)

@catenacyber
Copy link
Copy Markdown
Contributor Author

Replaced by #10091

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants