From: Richard Whitehouse Date: Sat, 4 Nov 2017 19:03:48 +0000 (+0000) Subject: Support Via header X-Git-Url: https://git.richardwhiuk.com/?a=commitdiff_plain;h=00ba5ea56a2ed54307a46a503a500efdbd321a71;p=rust-sip.git Support Via header --- diff --git a/src/codec.rs b/src/codec.rs index e832b9c..106b977 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -448,7 +448,8 @@ mod tests { atlanta.com;lr>\r\nServer:rust-sip \ tokio\r\nSubject:Foobaz\r\nSupported:rec\r\nTimestamp:1 \ 2\r\nTo:;tag=287447\r\nUnsupported:\ - 100rel\r\nUser-Agent:rust-sip\r\nVia: localhost\r\n\r\n") + 100rel\r\nUser-Agent:rust-sip\r\nVia:SIP/2.0/UDP \ + pc33.atlanta.com;branch=z9hG4bK776asdhds\r\n\r\n") }); let finished = request.and_then(|(socket, _request)| { diff --git a/src/parser.rs b/src/parser.rs index 86f3cd5..a4843da 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -17,7 +17,8 @@ use types::{PathSegment, HostPort, Host, Hostname, UriParameter, UriHeader, UriH Credentials, CallId, Purpose, InfoParam, Info, NameAddr, ContactParam, Target, Contact, DispositionType, Handling, DispositionParam, ContentCoding, Day, Month, Date, Time, DateTime, ErrorUri, FromParam, From, Priority, Domain, DigestChallenge, - Challenge, OptionTag, Route, ReplyTo, RetryAfterParam, RetryAfter, Server, ToParam, To}; + Challenge, OptionTag, Route, ReplyTo, RetryAfterParam, RetryAfter, Server, ToParam, + To, Protocol, SentProtocol, Received, ViaParam, Via}; pub fn float(input: &[u8]) -> IResult<&[u8], f32> { flat_map!(input, @@ -1158,6 +1159,51 @@ named!(user_agent_header>, preceded!( tag!(b" "), server))); +named!(protocol_name, alt!( + tag!(b"SIP") => { |_| Protocol::SIP } | + token => { |t| Protocol::Other(t) } +)); + +named!(transport, alt!( + tag!(b"UDP") => { |_| Transport::Udp } | + tag!(b"TCP") => { |_| Transport::Tcp } | + tag!(b"TLS") => { |_| Transport::Tls } | + tag!(b"SCTP") => { |_| Transport::Sctp } | + token => { |t| Transport::Other(t) })); + +named!(sent_protocol, tuple!( + terminated!(protocol_name, tag!("/")), + terminated!(token, tag!("/")), + transport)); + +use self::hostport as sent_by; + +named!(received, alt!( + ipv4_address => { |(a, b, c, d)| Received::Ipv4Address(a,b,c,d) } | + ipv6_address => { |i| Received::Ipv6Address(i) } +)); + +named!(via_param, alt!( + preceded!(tag!(b"ttl="), number) => { |t| ViaParam::Ttl(t) } | + preceded!(tag!(b"maddr="), host) => { |h| ViaParam::Maddr(h) } | + preceded!(tag!(b"received="), received) => { |r| ViaParam::Received(r) } | + preceded!(tag!(b"branch="), token) => { |t| ViaParam::Branch(t) } | + generic_param => { |g| ViaParam::Extension(g) } +)); + +named!(via, tuple!( + terminated!(sent_protocol, tag!(b" ")), + sent_by, + many0!(preceded!( + tag!(b";"), + via_param)))); + +named!(via_header>, preceded!( + alt!(tag!(b"Via:") | tag!("v:")), + separated_nonempty_list!( + tag!(b","), + via))); + named!(pub header
, alt!( // RFC 3261 Headers accept_header => { |a| Header::Accept(a) } | @@ -1200,5 +1246,6 @@ named!(pub header
, alt!( timestamp_header => { |t| Header::Timestamp(t) } | to_header => { |t| Header::To(t) } | unsupported_header => { |u| Header::Unsupported(u) } | - user_agent_header => { |u| Header::UserAgent(u) } + user_agent_header => { |u| Header::UserAgent(u) } | + via_header => { |v| Header::Via(v) } )); diff --git a/src/types.rs b/src/types.rs index 78c00ff..298bb80 100644 --- a/src/types.rs +++ b/src/types.rs @@ -397,6 +397,31 @@ pub enum ToParam { pub type To = (Target, Vec); +#[derive(Debug)] +pub enum Protocol { + SIP, + Other(Vec), +} + +pub type SentProtocol = (Protocol, Vec, Transport); + +#[derive(Debug)] +pub enum Received { + Ipv4Address(u8, u8, u8, u8), + Ipv6Address(Vec), +} + +#[derive(Debug)] +pub enum ViaParam { + Ttl(u32), + Maddr(Host), + Received(Received), + Branch(Vec), + Extension(GenericParam), +} + +pub type Via = (SentProtocol, HostPort, Vec); + #[derive(Debug)] pub enum Header { Accept(Vec), @@ -440,5 +465,6 @@ pub enum Header { To(To), Unsupported(Vec), UserAgent(Vec), + Via(Vec), Extension { name: String, value: String }, }