pion / sdp Goto Github PK
View Code? Open in Web Editor NEWA Go implementation of the SDP
Home Page: https://pion.ly/
License: MIT License
A Go implementation of the SDP
Home Page: https://pion.ly/
License: MIT License
I suggest to avoid dependency on ice package by implementing an sdp.Candidate object instead.
Advantages
Disadvantages
Add support for MSRP media proto types defined in https://datatracker.ietf.org/doc/html/rfc4975#section-8.1
There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.
Error type: undefined. Note: this is a nested preset so please contact the preset author if you are unable to fix it yourself.
As introduced by Go 1.18
@backkem do you remember the intent of this comment?
This issue provides visibility into Renovate updates and their statuses. Learn more
This repository currently has no open or pending branches.
Currently the Pion SDP parser is hand generated, if it is working great, then I have little to add,
but if people keep running into issues it might be time to use an RFC/ABNF generated parser
for Go.
https://github.com/cameron-elliott/sdp-antlr-abnf
https://github.com/cameron-elliott/sdp-antlr-abnf/tree/master/output-go
Antlr is a mature, quality parser generator.
The ABNF has been pulled from the original SDP RFCs, and hand tweaked to fix small issues.
The C# parser is being used in a commercial SIP project.
This is only really needed if people feel the hand parser is running into roadblocks.
A fair bit of work would still need to be done to match the current Pion data structures.
The big benefit would be one parity is reached, there would be little coding needing for parsing, really just mapping tree results into data structures.
In the end, I would say this is only useful if the current code seems like it has outlived it useful life.
Is there any reason why the parser's Unmarshal function takes a string
instead of a []byte
like other Go marshalers?
I think there might be a performance penalty with using a string.
Also, would it ever make sense for Marshal
to return an error? I haven't read the sdp spec, but I imagine there are some length limits or something.
Add a variant of Unmarshal()
that doesn't return an error if an attribute or value is unknown.
Some custom implementations might want to use their own custom attributes, or custom values in some of these attributes (e.g. a custom bandwidth type in a b=
attribute), that their clients have extra logic to decode. Currently, Unmarshal()
returns a syntax error if such attribute or value is found in the session description; it would be great to have a variant of that function which would add any attribute to the Attributes
field of the session or media description and not return an error if it fails to recognise the attribute or a value in its content.
Hello,
I did my research in the /v3 version
Nowhere in the documentation nor in the source code I found the place to define ports for stream transports.
The ports used are between 1024 (or maybe 16384) and 65535.
It is common that in the use of ipbx this must be restricted.I don't know if the suggestion should be made here or in the pion/rtp project.
Thanks for everything
The fuzzer returned this test case. Not sure if it's a bug or not, but it's a case where Unmarshal(x).Marshal() != x
Unmarshaling this SDP:
v=0
o=0 0 0 IN IP4 0
s=
t=0 0
Produces this SDP when marshaled:
v=0
o= 0 0
s=
The last tag is from 2020, please add a new one
unmarshalOrigin
doesn't properly validate yet.
Trying to negotiate RFC 8888 a=rtcp-fb:* ack ccfb
feedback with a media server (Janus) that is offering the feature.
Pion parses the attribute and adds it to the SDP answer
Pion can not parse the attribute due to the presence of wildcard *
(as requested by RFC 8888).
Lines 171 to 173 in 9704a3f
The problem is that the parsing helper is expecting a PT number, whereas the RFC 8888 mandates a wildcard:
The payload type used with "ccfb" feedback MUST be the wildcard type
("*"). This implies that the congestion control feedback is sent for
all payload types in use in the session, including any Forward Error
Correction (FEC) and retransmission payload types.
Unmarshaling this SDP produces a SEGFAULT
v=0
o=1 4 0 IN IP4 0
s=
t=0 0
a=
m=audio 6 UDP/TLS/RTP/AVP 197
c=IN IP4 63.245.221.198
a=candidate:0 1 UDP 2122187007 2620:101:80fc:224:8dd:cbf5:24c1:35db 52629 typ host
a=candidate:2 1 UDP 2122252543 2620:101:80fc:224:219d:9e56:e0e3:9503 52630 typ host
a=candidate:4 1 UDP 2122121471 10.252.25.57 53802 typ host
a=candidate:6 1 TCP 2105458943 2620:101:80fc:224:8dd:cbf5:24c1:35db 9 typ host tcptype active
a=candidate:7 1 TCP 2105524479 2620:101:80fc:224:219d:9e56:e0e3:9503 9 typ host tcptype active
a=candidate:8 1 TCP 2105393407 10.252.25.57 9 .221.198
a=rtcp-f4
a=candidate:0 1 UDP 2122252543 10.20.24.132 63416 typ host
a=candidate:4 1 TCP 2105524479 10.20.24.132 9 typ host tcptype active
a=candidate:0 2 UDP 2122252542 10.20.24.132 54932 typ host
a=candidate:4 2 TCP 2105524478 10.20.24.132 9 typ host tcptype active
a=candidate:1 1 UDP 1686052863 64.134.220.204 63416 typ srflx raddr 10.20.24.132 rport 63416
a=candidate:1 2 UDP 1686052862 64.134.220.204 54932 typ srflx raddr 10.20.24.132 rport 54932
a=sendrecv
a=e
a=rtpmap:109 opus/48000/2
a=rtpmap:9 G722/8000/1
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=setup:actpass
a=ssrc:462093353 cname:{54ace55b-4950-d04a-a0f0-07f22b0a82a8}
m=video 62026 UDP/TLS/RTP/SAVPF 120 121 126 97
c=IN IP4 64.134.220.204
a=candidate:0 1 UDP 2122252543 10.20.24.132 62026 typ host
a=candpwd:93Lyy3CWKSpg5URW2cNHi+zt
a=ice-ufrag:+DGd
a=mid:sdparta_1
a=rtcp:9 IN IP4 0.0.0.0
a=rtcp-fb:126 ccm fir
a=rtcp-fb:126 nack
a=rtcp-fb:126 nack pli
a=rtcp-fb:126 goog-remb
a=rtcp-mux
a=rtpmap:126 H264/90000
a=setup:active
a=ssrc:3151863948 cname:xuQ/XUzBRVyBhL9u
a=ssrc:3151863948 msid:2dd448fe-f34c-4f24-92d7-c895d692cbe0 4432de0c-036d-46ef-9a57-f7969eaa21a448 mslabel:2dd448fe-f34c-4f24-92d7-c895d692cbe0
a=ssrc:3151863948 label:4432de0c-036d-46ef-9a57-f7969eaa21a4
m=application 9 DTLS/SCTP 5000
c=IN IP4 0.0.0.0
b=AS:30
a=sendrecv
a=fingerprint:sha-256 2D:64:9F:C4:56:EB:FA:2A:BD:F3:99:83:29:F8:22:49:55:1B:6D:8E:C6:BD:A0:2E:B1:EB:8A:B5:71:F4:EC:3A
a=ice-pwd:93Lyy3CWKSpg5URW2cNHi+zt
a=ice-ufrag:+DGd
a=mid:sdparta_2
a=s����������������������������������������������������������fe-f34c-4f24-92d7-c895d692cbe0
m=audio 9 UDP/TLS/RTP/SAVPF 109 9 0 8 101
c=IN IP4 0.0.0.0
a=candidate:1150189783 1 udp 2113937151 10.20.24.132 51738 typ host generation 0 ufrag +DGd network-cost 50
a=sendrecv
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=fingerprint:sha-256 2D:64:9F:C4:56:EB:FA:2A:BD:F3:99:83:29:F8:22:49:55:1B:6D:8E:C6:BD:A0:2E:B1:EB:8A:B5:71:F4:EC:3A
a=fmtp:109 maxplaybackrate=0;stereo=0;useinbandfec=1
a=ice-pwd:93Lyy3CWKSpg5URW2cNHi+zt
a=ice-ufrag:+DGd
a=mid:sdparta_0
a=rtcp:60781116962625945IN IP4 0.0.0.0
a=rtcp-mux
a=rtpmap:109 opus/48000/2
a=rtpmap:9 G722/8000/1
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=setup:active
a=ssrc:1719255109 cname:xuQ/XUzBRVyBhL9u
a=ssrc:1719255109 msid:2dd448fe-f34c-4f24-92d7-c895d692cbe0 728ef582-b1cb-4074-abc0-b066f5508466
a=ssrc:1719255109 mslabel:2dd448fe-f34c-4f24-92d7-c895d692cbe0
a=ssrc:1719255l910 abel:728ef582-b1cb-4074-abc0-b066f5508466
m=video 9 UDP/TLS/RTP/SAVPF 126
c=IN IP4 0.0.0.0
a=sendrecv
a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
a=extmap:1 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=fingerprint:sha-256 2D:64:9F:C4:56:EB:FA:2A:BD:F3:99:83:29:F8:22:49:55:1B:6D:8E:C6:BD:A0:2E:B1:EB:8A:B5:71:F4:EC:3A
a=fmtp:126 profile-level-id=42e01f;level-asymmetrY-allowed=1;packetization-mode=1
a=ice-pwd:93Lyy3CWKSpg5URW2cNHi+zt
a=ice-ufrag:+DGd
a=mid:sdparta_1
a=rtcp:9 IN IP4 0.0.0.0
a=rtcp-fb:126 ccm fir
a=rtcp-fb:126 nack
a=rtcp-fb:126 nack pli
a=rtcp-fb:126 goog-remb
a=rtcp-mux
a=rtpmap:126 H264/90000
a=setup:active
a=ssrc:3151863948 cname:xuQ/XUzBRVyBhL9u
a=ssrc:3151863948 msid:2dd448fe-f34c-4f24-92d7-c895d692cbe0 4432de0c-036d-46ef-9a57-f7969eaa21a4
a=ssrc:3151(63948 mslabel:2dd448fe-f34c-4f24-92d7-c895d692cbe0
a=ssrc:3151863948 label:4432de0c-036d-46ef-9a57-f7969eaa21a4
m=application 9 DTLS/SCTP 5000
c=IN IP4 0.0.0.0
b=AS:30
a=sendrecv
a=fingerprint:sha-256 2D:64:9F:C4:56:EB:FA:2A:BD:F3:99:83:29:F8:22:49:55:1B:6D:8E:C6:BD:A0:2E:B1:EB:8ndex4 sr=8000,mode=any
a=rtp/1
a=rtpmap:1241754aa
a=ice-ufrag:c2cabe Speex/8000/1
a=control:trackID=
a=fmtp:96 profilemap:�124 Speex/8000/1
a=control:trackID=
a=fmtp:96 profile-lev�������������������������������������55
a=mid:sdpart�a7f-a29b-0b41-9ee7-50f38b59c2df}
a=rtcp:57451 IN IP4 63.245.221.198
a=rtcp-mux
a=rtpmap:109 opus/48000/2
a=rtpmap:9 G722/8000/1
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=setup:actpass
a=ssrc:1648141107 cname:{df386eca-8c30-4448-9e97-911468065c6b}
m=video 64677 UDP/TLS/RTP/SAVPF 120 121 126 97
c=IN IP4
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x10cd187]
goroutine 1 [running]:
github.com/pions/sdp.(*Address).String(0x0, 0xc0000104d0, 0x1)
/var/folders/f2/q9n7pkjs47j91q2hjrmzddhc0000gn/T/go-fuzz-build226374785/gopath/src/github.com/pions/sdp/common_description.go:46 +0x37
github.com/pions/sdp.(*ConnectionInformation).String(0xc0000948a0, 0xc000142600)
/var/folders/f2/q9n7pkjs47j91q2hjrmzddhc0000gn/T/go-fuzz-build226374785/gopath/src/github.com/pions/sdp/common_description.go:32 +0x5e
github.com/pions/sdp.(*SessionDescription).Marshal(0xc00009c120, 0xc0000c4000, 0x1267)
/var/folders/f2/q9n7pkjs47j91q2hjrmzddhc0000gn/T/go-fuzz-build226374785/gopath/src/github.com/pions/sdp/marshal.go:101 +0xbf3
github.com/pions/sdp.Fuzz(0x4210000, 0x1267, 0x200000, 0x10f6f00)
/var/folders/f2/q9n7pkjs47j91q2hjrmzddhc0000gn/T/go-fuzz-build226374785/gopath/src/github.com/pions/sdp/fuzz.go:23 +0xab
go-fuzz-dep.Main(0x1118fc8)
/var/folders/f2/q9n7pkjs47j91q2hjrmzddhc0000gn/T/go-fuzz-build226374785/goroot/src/go-fuzz-dep/main.go:49 +0xad
main.main()
/var/folders/f2/q9n7pkjs47j91q2hjrmzddhc0000gn/T/go-fuzz-build226374785/gopath/src/github.com/pions/sdp/go.fuzz.main/main.go:10 +0x2d
exit status 2
Support more values for the bandwidth types when parsing b=
attributes, namely the ones described in RFC3890 and RFC3556.
Implementation of protocols using SDP (whether it's SIP, WebRTC or others) might want or need to use values for the bandwidth type other than the two values defined in RFC4566. Currently using anything other than CT
or AS
in the b=
attribute of a SDP payload (either for the session or a media) and attempting to unmarshal it with pion/sdp results in an "invalid syntax" error. Because parsing this attribute happens in an unexported function in the unmarshal code, this support can't be added by the VoIP implementation using this library, so it needs to happen in this library itself.
SDP, together with RTSP, is used in most security cameras to serve their live streams, but not all of them fully respect the RFC specification. A versatile SDP library should handle these edge cases too.
Hello, first of all thanks for the beautifully-organized WebRTC implementation, that allows developers to pick exactly the components they need (sdp, srtp, rtcp, webrtc) without the effort of downloading the entire framework.
I'm the author of rtsp-simple-server, a RTSP server/proxy that allows to publish, pull and read live streams. RTSP is a RFC specification that, like WebRTC, uses SDP to describe available medias, in order to publish or read them. While WebRTC is mostly used to communicate with browsers, that are limited in quantity and can be upgraded to the last version, RTSP is mostly used to communicate with security cameras, which use embedded hardware and software, that cannot be upgraded, are very different one from another and use different SDP implementations. Therefore, even with recent hardware, i often have to deal with SDPs like this one:
"v=0
m=video 0 RTP/AVP/TCP 96
a=rtpmap:96 H265/90000
a=fmtp:96 sprop-vps=QAEMAf//AWAAAAMAsAAAAwAAAwB4FwJA; sprop-sps=QgEBAWAAAAMAsAAAAwAAAwB4oAKggC8c1YgXuRZFL/y5/E/qbgQEBAE=; sprop-pps=RAHAcvBTJA==;
a=control:streamid=0
m=audio 0 RTP/AVP/TCP 97
a=rtpmap:97 mpeg4-generic/44100/2
a=fmtp:97 profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3;config=1210
a=control:streamid=1
This are the differences i found with respect to the specification:
I think that a unique SDP library would be a great addon for the Go ecosystem, hence my proposal is to support these edge cases, that differs from the specification and require some little changes.
I considered writing a dedicated SDP library, but i prefer contributing to the main one.
I already produced a patch that would allow pion/sdp to support non-canonical SDPs, but before opening a PR i want to understand if you're interested in this feature or not.
sdp support transport-cc
RFC:
https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01
https://webrtc.org/experiments/rtp-hdrext/transport-wide-cc-02/
rtp and rtcp support transport-cc
RFC:
https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01
https://webrtc.org/experiments/rtp-hdrext/transport-wide-cc-02/
Code:
see TransportSequenceNumber and TransportSequenceNumberV2:
https://chromium.googlesource.com/external/webrtc/+/HEAD/modules/rtp_rtcp/source/rtp_header_extensions.h#93
https://chromium.googlesource.com/external/webrtc/+/HEAD/modules/rtp_rtcp/source/rtp_header_extensions.cc#235
github.com/pion/sdp/[email protected]/unmarshal.go
If Input below SDP session, it will report SDP syntax error.
v=0
o=LucentFS5000 1560282872 1560282872 IN IP4 test.com
s=-
t=0 0
c=IN IP4 10.243.83.56
unmarshal will parse c line in s9. And it will lead to syntax err.
func s9(l *lexer)
After change c line order with t line, it works well. it seems s12 handle the c line.
v=0
o=LucentFS5000 1560282872 1560282872 IN IP4 test.com
s=-
c=IN IP4 10.243.83.56
t=0 0
Any reason for SDP session part c line go to different state?
What details meaning for s9, s12, s4 etc?
Since pion/sdp parse, take below SDP as syntax err, can I know it break which RFC?
v=0
o=LucentFS5000 1560282872 1560282872 IN IP4 test.com
s=-
t=0 0
c=IN IP4 10.243.83.56 -----> c line after t line, or before t line, goes to different state.
Please let me know c line after t line break any RFC?
I can't find anything to support it at RFC4655, while, just very draft checking.
If no RFC forbidden it, how about handle c line without order sensitive?
A tiny support ticket to add go.mod
. I already created a PR for this #5 . Just need to fix it up.
We need to replace github.com/pkg/errors
with just fmt.Errorf()
I need to get the fingerprint of a given sessions description.
I authorize clients based on their fingerprints - I need a way to get the client's fingerprint so I can check if it's in my authorized fingerprints file.
I'm using regex do get the fingerprint directly from the description's string.
There is already WithFingerprint()
function to set the sd's fingerprint, this complements it.
Hi guys.
I noticed this error while parsing the SDP from my Amazon Show Echo. It seems to be coming from here: https://github.com/pion/sdp/blob/master/util.go#L275
Is this because a certain type of codecs is missing? I am stuck here. Any ideas ?
v=0
o=- 3895088739 3895088739 IN IP4 0.0.0.0
s=a 2 z
c=IN IP4 0.0.0.0
t=0 0
a=group:BUNDLE video0
m=audio 1 UDP/TLS/RTP/SAVPF 96 0 8
a=candidate:1 1 UDP 2013266431 3.95.151.25 56688 typ host
a=candidate:2 1 TCP 1015021823 3.95.151.25 9 typ host tcptype active
a=candidate:3 1 TCP 1010827519 3.95.151.25 51196 typ host tcptype passive
a=candidate:1 2 UDP 2013266430 3.95.151.25 52820 typ host
a=candidate:2 2 TCP 1015021822 3.95.151.25 9 typ host tcptype active
a=candidate:3 2 TCP 1010827518 3.95.151.25 53717 typ host tcptype passive
a=setup:actpass
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=rtpmap:96 opus/48000/2
a=rtcp:9 IN IP4 0.0.0.0
a=rtcp-mux
a=sendrecv
a=mid:audio0
a=ssrc:217587823 cname:user3544533498@host-4ee73c97
a=ice-ufrag:MVss
a=ice-pwd:xxxxxx
a=fingerprint:sha-256 92:83:9F:E2:0E:A8:B2:17:2B:99:1F:D9:9F:8A:93:8B:18:FD:75:F9:0D:0D:D9:4C:6C:75:27:F6:E2:A1:7F:4D
m=video 1 UDP/TLS/RTP/SAVPF 99
a=candidate:1 1 UDP 2013266431 3.95.151.25 56688 typ host
a=candidate:3 1 TCP 1010827519 3.95.151.25 51196 typ host tcptype passive
a=candidate:1 2 UDP 2013266430 3.95.151.25 52820 typ host
a=candidate:2 2 TCP 1015021822 3.95.151.25 9 typ host tcptype active
a=candidate:3 2 TCP 1010827518 3.95.151.25 53717 typ host tcptype passive
a=candidate:2 1 TCP 1015021823 3.95.151.25 9 typ host tcptype active
b=AS:2500
a=setup:actpass
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=rtpmap:99 H264/90000
a=rtcp:9 IN IP4 0.0.0.0
a=rtcp-mux
a=sendrecv
a=mid:video0
a=rtcp-fb:99 nack
a=rtcp-fb:99 nack pli
a=rtcp-fb:99 ccm fir
a=ssrc:2169777458 cname:user3544533498@host-4ee73c97
a=ice-ufrag:MVss
a=ice-pwd:xxxxx
a=fingerprint:sha-256 92:83:9F:E2:0E:A8:B2:17:2B:99:1F:D9:9F:8A:93:8B:18:FD:75:F9:0D:0D:D9:4C:6C:75:27:F6:E2:A1:7F:4D
SDP Unmarshal (lexer) syntax errors are unwieldy and difficult to work with. Let's make them easier to work with and more logable.
An SDP syntax error from the lexer echoes the full SDP with "==>" "<==" cursors and doesn't actually say that it's a syntax error. As I'm sure you are well aware, an SDP can be many KB in size, making these strings absolutely enormous compared to idiomatic error strings.
Without an exported type or a well known prefix or an identifying method attache these errors, it's even hard to detect these to handle them differently in the application.
Straw man improved error string: syntax error: at pos 50: '='
"Reduced" example: https://go.dev/play/p/ylGW1n7YBrO
const basicSDP = "v=0\r\n" +
"o=jdoe 2890844526 2890842807 IN IP4 10.10.10.100\r\n" +
"s=SDP Seminar\r\n"
func main() {
badSDP := basicSDP + strings.Repeat("a=junk\r\n", 100)
s := &sdp.SessionDescription{}
err := s.Unmarshal([]byte(badSDP))
fmt.Printf("error type: %T\n", err)
fmt.Printf("%v\n", err)
}
Hi~
I took a sdp file from a webcam, but it failed to parse
[
v=0
o=NVR 1585015269 1585015269 IN IP4 0.0.0.0
s=3GPP Unicast SDP
c=IN IP4 0.0.0.0
t=0 0
a=range:npt=0-
a=control:*
m=video 0 RTP/AVP 96
a=control:video_0
a=rtpmap:96 H264/90000
a=fmtp:96 profile-level-id=42002a;sprop-parameter-sets=Z0IAKp2oHgCJ+WbgICAgQA==,aM48gA==;packetization-mode=0
m=audio 0 RTP/AVP 8
a=control:audio_0
a=rtpmap:8 PCMA/8000
]
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.