#stun #zero-copy #message-parser #io #stun-parser

无std stun-bytes

STUN消息协议解析器的底层基础

2个稳定版本

1.0.1 2022年11月7日

#18 in #stun

Download history 235/week @ 2024-03-13 247/week @ 2024-03-20 206/week @ 2024-03-27 234/week @ 2024-04-03 176/week @ 2024-04-10 205/week @ 2024-04-17 204/week @ 2024-04-24 208/week @ 2024-05-01 251/week @ 2024-05-08 261/week @ 2024-05-15 214/week @ 2024-05-22 213/week @ 2024-05-29 223/week @ 2024-06-05 248/week @ 2024-06-12 215/week @ 2024-06-19 270/week @ 2024-06-26

982 每月下载量
用于 stun-format

MIT 许可证

17KB
300

stun-bytes

Github Crates.io Codacy grade Crates.io

STUN消息协议解析器的底层基础。

亮点

  • 零拷贝
  • 无std
  • RFC无关

STUN消息结构

头部

 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|    Message Type (16 bits)   |     Message Length (16 bits)    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                     Magic Cookie (32 bits)                    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                    Transaction ID (96 bits)                   |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

注意:RFC5389以来,Transaction ID字段已分为Magic CookieTransaction ID。如果您想遵循这种拆分,请启用cookie功能。

属性

 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|        Type (16 bits)         |        Length (16 bits)       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Value (variable)                     ..
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

示例

解析STUN消息

const MSG: [u8; 28] = [
    0x00, 0x01,                     // type: Binding Request
    0x00, 0x08,                     // length: 8 (header does not count)
    0x21, 0x12, 0xA4, 0x42,         // magic cookie
    0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01,         // transaction id
    0x00, 0x03,                     // type: ChangeRequest
    0x00, 0x04,                     // length: 4 (only value bytes count)
    0x00, 0x00, 0x00, 0x40 | 0x20,  // change both ip and port
];

let msg = ByteMsg::from_arr(&MSG);

assert_eq!(&MSG[0..2], msg.typ()?);     // read type field
assert_eq!(&MSG[2..4], msg.len()?);     // read length field
assert_eq!(&MSG[4..8], msg.cookie()?);  // read cookie field (enable 'cookie' feature first)
assert_eq!(&MSG[8..20], msg.tid()?);    // read transaction id field
assert_eq!(&MSG[20..28], msg.attrs()?); // read all attribute bytes

let attr = msg.attrs_iter().next()?;    // iterate over attributes

assert_eq!(&MSG[20..22], attr.typ()?);  // read attribute type field
assert_eq!(&MSG[22..24], attr.len()?);  // read attribute length field
assert_eq!(&MSG[24..28], attr.val()?);  // read attribute value field

创建STUN消息

const MSG: [u8; 28] = [
    0x00, 0x01,                     // type: Binding Request
    0x00, 0x08,                     // length: 8 (header does not count)
    0x21, 0x12, 0xA4, 0x42,         // magic cookie
    0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01,         // transaction id
    0x00, 0x03,                     // type: ChangeRequest
    0x00, 0x04,                     // length: 4 (only value bytes count)
    0x00, 0x00, 0x00, 0x40 | 0x20,  // change both ip and port
];

let mut buf = [0u8; MSG.len()];
let mut msg = ByteMsgMut::from_arr_mut(&mut buf);

msg.typ()?.copy_from(MSG.carved()?);                            // write type field
// msg.len()?.copy_from(MSG.carve(2)?);                         // length field updates automatically
msg.cookie()?.copy_from(MSG.carve(4)?);                         // write cookie field
msg.tid()?.copy_from(MSG.carve(8)?);                            // write transaction id field
msg.add_attr(MSG.carve(20)?, MSG.carve(22)?, MSG.get(24..28)?); // write attribute (type, length, value)

assert_eq!(&MSG, msg.as_bytes());

贡献指南

欢迎提交拉取请求。请确保您的贡献遵循上面原则部分。

依赖项

~14KB