Support Via header
authorRichard Whitehouse <github@richardwhiuk.com>
Sat, 4 Nov 2017 19:03:48 +0000 (19:03 +0000)
committerRichard Whitehouse <github@richardwhiuk.com>
Sat, 4 Nov 2017 19:03:48 +0000 (19:03 +0000)
src/codec.rs
src/parser.rs
src/types.rs

index e832b9cbdf25c3b6b319c8b0caa6f653f63e9fa4..106b977d7d33dc654721738d1203740888b075f3 100644 (file)
@@ -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:<sip:operator@cs.columbia.edu>;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)| {
index 86f3cd51c6838ef269c392e85c3660fef0d7c33b..a4843da55294870710c87c550466bcf89cb0050e 100644 (file)
@@ -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<Vec<Server>>, preceded!(
                tag!(b" "),
                server)));
 
+named!(protocol_name<Protocol>, alt!(
+       tag!(b"SIP") => { |_| Protocol::SIP } |
+       token => { |t| Protocol::Other(t) }
+));
+
+named!(transport<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<SentProtocol>, tuple!(
+       terminated!(protocol_name, tag!("/")),
+       terminated!(token, tag!("/")),
+       transport));
+
+use self::hostport as sent_by;
+
+named!(received<Received>, alt!(
+    ipv4_address => { |(a, b, c, d)| Received::Ipv4Address(a,b,c,d) } |
+    ipv6_address => { |i| Received::Ipv6Address(i) }
+));
+
+named!(via_param<ViaParam>, 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<Via>, tuple!(
+       terminated!(sent_protocol, tag!(b" ")),
+       sent_by,
+       many0!(preceded!(
+               tag!(b";"),
+               via_param))));
+
+named!(via_header<Vec<Via>>, preceded!(
+       alt!(tag!(b"Via:") | tag!("v:")),
+       separated_nonempty_list!(
+               tag!(b","),
+               via)));
+
 named!(pub header<Header>, alt!(
 // RFC 3261 Headers
        accept_header => { |a| Header::Accept(a) } |
@@ -1200,5 +1246,6 @@ named!(pub header<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) }
 ));
index 78c00ff398084f35389f2318aa59186efaa813bc..298bb803df9b2c21d5afd87d4043f4ca5b8bd2e4 100644 (file)
@@ -397,6 +397,31 @@ pub enum ToParam {
 
 pub type To = (Target, Vec<ToParam>);
 
+#[derive(Debug)]
+pub enum Protocol {
+    SIP,
+    Other(Vec<u8>),
+}
+
+pub type SentProtocol = (Protocol, Vec<u8>, Transport);
+
+#[derive(Debug)]
+pub enum Received {
+    Ipv4Address(u8, u8, u8, u8),
+    Ipv6Address(Vec<u8>),
+}
+
+#[derive(Debug)]
+pub enum ViaParam {
+    Ttl(u32),
+    Maddr(Host),
+    Received(Received),
+    Branch(Vec<u8>),
+    Extension(GenericParam),
+}
+
+pub type Via = (SentProtocol, HostPort, Vec<ViaParam>);
+
 #[derive(Debug)]
 pub enum Header {
     Accept(Vec<AcceptRange>),
@@ -440,5 +465,6 @@ pub enum Header {
     To(To),
     Unsupported(Vec<OptionTag>),
     UserAgent(Vec<Server>),
+    Via(Vec<Via>),
     Extension { name: String, value: String },
 }