commit 0c7ddeb1d0de1699109c85f82a4f3e1112793a90 Author: David Fifield david@bamsoftware.com Date: Tue Aug 15 17:09:53 2017 -0700
Parse.ipFromSDP function. --- proxy/spec/util.spec.coffee | 111 ++++++++++++++++++++++++++++++++++++++++++++ proxy/util.coffee | 11 +++++ 2 files changed, 122 insertions(+)
diff --git a/proxy/spec/util.spec.coffee b/proxy/spec/util.spec.coffee index 4e5ab45..1d99b04 100644 --- a/proxy/spec/util.spec.coffee +++ b/proxy/spec/util.spec.coffee @@ -90,6 +90,117 @@ describe 'Parse', -> expect Parse.address '[1:2::ffff:1.2.3.4]:4444' .toEqual { host: '1:2::ffff:1.2.3.4', port: 4444 }
+ describe 'ipFromSDP', -> + testCases = [ + # https://tools.ietf.org/html/rfc4566#section-5 + sdp: """ + v=0 + o=jdoe 2890844526 2890842807 IN IP4 10.47.16.5 + s=SDP Seminar + i=A Seminar on the session description protocol + u=http://www.example.com/seminars/sdp.pdf + e=j.doe@example.com (Jane Doe) + c=IN IP4 224.2.17.12/127 + t=2873397496 2873404696 + a=recvonly + m=audio 49170 RTP/AVP 0 + m=video 51372 RTP/AVP 99 + a=rtpmap:99 h263-1998/90000 + """ + expected: '224.2.17.12' + , + # Missing c= line + sdp: """ + v=0 + o=jdoe 2890844526 2890842807 IN IP4 10.47.16.5 + s=SDP Seminar + i=A Seminar on the session description protocol + u=http://www.example.com/seminars/sdp.pdf + e=j.doe@example.com (Jane Doe) + t=2873397496 2873404696 + a=recvonly + m=audio 49170 RTP/AVP 0 + m=video 51372 RTP/AVP 99 + a=rtpmap:99 h263-1998/90000 + """ + expected: undefined + , + # Single line, IP address only + sdp: "c=IN IP4 224.2.1.1\n" + expected: '224.2.1.1' + , + # Same, with TTL + sdp: "c=IN IP4 224.2.1.1/127\n" + expected: '224.2.1.1' + , + # Same, with TTL and multicast addresses + sdp: "c=IN IP4 224.2.1.1/127/3\n" + expected: '224.2.1.1' + , + # IPv6, address only + sdp: "c=IN IP6 FF15::101\n" + expected: 'ff15::101' + , + # Same, with multicast addresses + sdp: "c=IN IP6 FF15::101/3\n" + expected: 'ff15::101' + , + # Multiple c= lines + sdp: """ + c=IN IP4 1.2.3.4 + c=IN IP4 5.6.7.8 + """ + expected: '1.2.3.4' + , + # Modified from SDP sent by snowflake-client. + sdp: """ + v=0 + o=- 7860378660295630295 2 IN IP4 127.0.0.1 + s=- + t=0 0 + a=group:BUNDLE data + a=msid-semantic: WMS + m=application 54653 DTLS/SCTP 5000 + c=IN IP4 1.2.3.4 + a=candidate:3581707038 1 udp 2122260223 192.168.0.1 54653 typ host generation 0 network-id 1 network-cost 50 + a=candidate:2617212910 1 tcp 1518280447 192.168.0.1 59673 typ host tcptype passive generation 0 network-id 1 network-cost 50 + a=candidate:2082671819 1 udp 1686052607 1.2.3.4 54653 typ srflx raddr 192.168.0.1 rport 54653 generation 0 network-id 1 network-cost 50 + a=ice-ufrag:IBdf + a=ice-pwd:G3lTrrC9gmhQx481AowtkhYz + a=fingerprint:sha-256 53:F8:84:D9:3C:1F:A0:44:AA:D6:3C:65:80:D3:CB:6F:23:90:17:41:06:F9:9C:10:D8:48:4A:A8:B6:FA:14:A1 + a=setup:actpass + a=mid:data + a=sctpmap:5000 webrtc-datachannel 1024 + """ + expected: '1.2.3.4' + , + # Improper character within IPv4 + sdp: """ + c=IN IP4 224.2z.1.1 + """ + expected: undefined + , + # Improper character within IPv6 + sdp: """ + c=IN IP6 ff15:g::101 + """ + expected: undefined + , + # Bogus "IP7" addrtype + sdp: "c=IN IP7 1.2.3.4\n" + expected: undefined + ] + + it 'parses SDP', -> + for test in testCases + # https://tools.ietf.org/html/rfc4566#section-5: "The sequence # CRLF + # (0x0d0a) is used to end a record, although parsers SHOULD be tolerant + # and also accept records terminated with a single newline character." + # We represent the test cases with LF line endings for convenience, and + # test them both that way and with CRLF line endings. + expect(Parse.ipFromSDP(test.sdp)?.toLowerCase()).toEqual(test.expected) + expect(Parse.ipFromSDP(test.sdp.replace(/\n/, "\r\n"))?.toLowerCase()).toEqual(test.expected) + describe 'query string', -> it 'should parse correctly', -> expect Query.parse '' diff --git a/proxy/util.coffee b/proxy/util.coffee index 3e0a08c..3cb4ff6 100644 --- a/proxy/util.coffee +++ b/proxy/util.coffee @@ -112,6 +112,17 @@ Parse = return null if null == units count * Number(units)
+ # Parse a connection-address out of the "c=" Connection Data field of a session + # description. Return undefined if none is found. + # https://tools.ietf.org/html/rfc4566#section-5.7 + ipFromSDP: (sdp) -> + for pattern in [ + /^c=IN IP4 ([\d.]+)(?:(?:/\d+)?/\d+)?(:? |$)/m, + /^c=IN IP6 ([0-9A-Fa-f:.]+)(?:/\d+)?(:? |$)/m, + ] + m = pattern.exec(sdp) + return m[1] if m? +
Params = getBool: (query, param, defaultValue) ->