diff --git a/go.mod b/go.mod index 9059d98303..729ed86b51 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.4.1 github.com/CortexFoundation/inference v1.0.2-0.20230307032835-9197d586a4e8 github.com/CortexFoundation/statik v0.0.0-20210315012922-8bb8a7b5dc66 - github.com/CortexFoundation/torrentfs v1.0.69-0.20241010111105-9de7a9574507 + github.com/CortexFoundation/torrentfs v1.0.69-0.20241014112616-2c6fbb777c44 github.com/VictoriaMetrics/fastcache v1.12.2 github.com/arsham/figurine v1.3.0 github.com/aws/aws-sdk-go-v2 v1.32.2 @@ -59,7 +59,7 @@ require ( github.com/stretchr/testify v1.9.0 github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d github.com/ucwong/color v1.10.1-0.20200624105241-fba1e010fe1e - github.com/urfave/cli/v2 v2.27.4 + github.com/urfave/cli/v2 v2.27.5 go.uber.org/automaxprocs v1.6.0 golang.org/x/crypto v0.28.0 golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c @@ -100,7 +100,7 @@ require ( github.com/anacrolix/multiless v0.4.0 // indirect github.com/anacrolix/stm v0.5.0 // indirect github.com/anacrolix/sync v0.5.3 // indirect - github.com/anacrolix/torrent v1.57.2-0.20241007003033-f21937e55137 // indirect + github.com/anacrolix/torrent v1.57.2-0.20241014100415-05ab0cad4774 // indirect github.com/anacrolix/upnp v0.1.4 // indirect github.com/anacrolix/utp v0.2.0 // indirect github.com/antlabs/stl v0.0.2 // indirect @@ -147,7 +147,7 @@ require ( github.com/elliotchance/orderedmap v1.6.0 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 // indirect - github.com/getsentry/sentry-go v0.29.0 // indirect + github.com/getsentry/sentry-go v0.29.1 // indirect github.com/go-llsqlite/adapter v0.1.0 // indirect github.com/go-llsqlite/crawshaw v0.5.5 // indirect github.com/go-logr/logr v1.4.2 // indirect @@ -190,21 +190,21 @@ require ( github.com/otiai10/copy v1.14.1-0.20240615124421-e40f4e6d0e0b // indirect github.com/otiai10/mint v1.6.3 // indirect github.com/pion/datachannel v1.5.9 // indirect - github.com/pion/dtls/v2 v2.2.12 // indirect - github.com/pion/ice/v2 v2.3.36 // indirect + github.com/pion/dtls/v3 v3.0.3 // indirect + github.com/pion/ice/v4 v4.0.2 // indirect github.com/pion/interceptor v0.1.37 // indirect github.com/pion/logging v0.2.2 // indirect - github.com/pion/mdns v0.0.12 // indirect + github.com/pion/mdns/v2 v2.0.7 // indirect github.com/pion/randutil v0.1.0 // indirect github.com/pion/rtcp v1.2.14 // indirect github.com/pion/rtp v1.8.9 // indirect github.com/pion/sctp v1.8.33 // indirect github.com/pion/sdp/v3 v3.0.9 // indirect - github.com/pion/srtp/v2 v2.0.20 // indirect - github.com/pion/stun v0.6.2-0.20230901070932-d1f1ac894921 // indirect - github.com/pion/transport/v2 v2.2.10 // indirect - github.com/pion/turn/v2 v2.1.6 // indirect - github.com/pion/webrtc/v3 v3.3.4 // indirect + github.com/pion/srtp/v3 v3.0.4 // indirect + github.com/pion/stun/v3 v3.0.0 // indirect + github.com/pion/transport/v3 v3.0.7 // indirect + github.com/pion/turn/v4 v4.0.0 // indirect + github.com/pion/webrtc/v4 v4.0.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.20.4 // indirect @@ -227,7 +227,7 @@ require ( github.com/tklauser/numcpus v0.9.0 // indirect github.com/ucwong/filecache v1.0.6-0.20230405163841-810d53ced4bd // indirect github.com/ucwong/go-ttlmap v1.0.2-0.20221020173635-331e7ddde2bb // indirect - github.com/ucwong/golang-kv v1.0.24-0.20241010105424-84c909d0d763 // indirect + github.com/ucwong/golang-kv v1.0.24-0.20241013181450-613f8dd1b92b // indirect github.com/ucwong/shard v1.0.1-0.20240327124306-59a521744cae // indirect github.com/wlynxg/anet v0.0.5 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect diff --git a/go.sum b/go.sum index 7fddfcee07..646d7a3069 100644 --- a/go.sum +++ b/go.sum @@ -70,8 +70,8 @@ github.com/CortexFoundation/statik v0.0.0-20210315012922-8bb8a7b5dc66/go.mod h1: github.com/CortexFoundation/torrentfs v1.0.13-0.20200623060705-ce027f43f2f8/go.mod h1:Ma+tGhPPvz4CEZHaqEJQMOEGOfHeQBiAoNd1zyc/w3Q= github.com/CortexFoundation/torrentfs v1.0.14-0.20200703071639-3fcabcabf274/go.mod h1:qnb3YlIJmuetVBtC6Lsejr0Xru+1DNmDCdTqnwy7lhk= github.com/CortexFoundation/torrentfs v1.0.20-0.20200810031954-d36d26f82fcc/go.mod h1:N5BsicP5ynjXIi/Npl/SRzlJ630n1PJV2sRj0Z0t2HA= -github.com/CortexFoundation/torrentfs v1.0.69-0.20241010111105-9de7a9574507 h1:bEKz2cBZ1cM2CvHXlhoO1NoR5LxAeIVEfKVFYQXx23E= -github.com/CortexFoundation/torrentfs v1.0.69-0.20241010111105-9de7a9574507/go.mod h1:WEVSjyy5u4HVD82hicfJIpHjIVVj9i1i1jp9/s8HXsQ= +github.com/CortexFoundation/torrentfs v1.0.69-0.20241014112616-2c6fbb777c44 h1:84EXGp66wkSWmAOklCv76xnROzVGN27sdefh4Ju23hE= +github.com/CortexFoundation/torrentfs v1.0.69-0.20241014112616-2c6fbb777c44/go.mod h1:HnSg3LUSwKuaLCrOV9+9eEKa7XVICRfNoSpw6phRytA= github.com/CortexFoundation/wormhole v0.0.2-0.20240624201423-33e289eb7662 h1:rmM5WDx5UX7V4LF1D8LtAOPDzcCKulpZ++NkP8/+Ook= github.com/CortexFoundation/wormhole v0.0.2-0.20240624201423-33e289eb7662/go.mod h1:ipzmPabDgzYKUbXkGVe2gTkBEp+MsDx6pXGiuYzmP6s= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= @@ -220,8 +220,8 @@ github.com/anacrolix/torrent v1.15.0/go.mod h1:MFc6KcbpAyfwGqOyRkdarUK9QnKA/FkVg github.com/anacrolix/torrent v1.15.1-0.20200504230043-cc5d2abe18e5/go.mod h1:QlOfgrCz5kbvhOz8M58dUwHY5SfZ9VbIvReZ0z0MdIk= github.com/anacrolix/torrent v1.15.1-0.20200619022403-dd51e99b88cc/go.mod h1:wuopQPC5+/M+zHYvhcA2vp5UCTm9rUc+VqjyBa882Q8= github.com/anacrolix/torrent v1.15.1-0.20200715061614-dd906f8fa72e/go.mod h1:XWo/fJN1oKgcjgxM+pUZpvalHfqHDs27BY5mBZjIQWo= -github.com/anacrolix/torrent v1.57.2-0.20241007003033-f21937e55137 h1:BEnPiupo2pR9/SY6L4HHA01/3QW18JAIhtK/JzVVBz0= -github.com/anacrolix/torrent v1.57.2-0.20241007003033-f21937e55137/go.mod h1:jtEHgUsUAJ9zGLNUQUIFHb3W5quMKoj5SCjfsKe22EI= +github.com/anacrolix/torrent v1.57.2-0.20241014100415-05ab0cad4774 h1:doeShZG+H2dm5hU2VTWhQ6CQaqMRNPBtxTdbUsCcwWQ= +github.com/anacrolix/torrent v1.57.2-0.20241014100415-05ab0cad4774/go.mod h1:n3SjHIE8oHXeH0Px0d5FXQ7cU4IgbEfTroen6B9KWJk= github.com/anacrolix/upnp v0.1.1/go.mod h1:LXsbsp5h+WGN7YR+0A7iVXm5BL1LYryDev1zuJMWYQo= github.com/anacrolix/upnp v0.1.2-0.20200416075019-5e9378ed1425/go.mod h1:Pz94W3kl8rf+wxH3IbCa9Sq+DTJr8OSbV2Q3/y51vYs= github.com/anacrolix/upnp v0.1.4 h1:+2t2KA6QOhm/49zeNyeVwDu1ZYS9dB9wfxyVvh/wk7U= @@ -494,8 +494,8 @@ github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILD github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= -github.com/getsentry/sentry-go v0.29.0 h1:YtWluuCFg9OfcqnaujpY918N/AhCCwarIDWOYSBAjCA= -github.com/getsentry/sentry-go v0.29.0/go.mod h1:jhPesDAL0Q0W2+2YEuVOvdWmVtdsr1+jtBrlDEVWwLY= +github.com/getsentry/sentry-go v0.29.1 h1:DyZuChN8Hz3ARxGVV8ePaNXh1dQ7d76AiB117xcREwA= +github.com/getsentry/sentry-go v0.29.1/go.mod h1:x3AtIzN01d6SiWkderzaH28Tm0lgkafpJ5Bm3li39O0= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= @@ -635,7 +635,6 @@ github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= @@ -986,30 +985,27 @@ github.com/pion/datachannel v1.4.16/go.mod h1:gRGhxZv7X2/30Qxes4WEXtimKBXcwj/3Ws github.com/pion/datachannel v1.5.9 h1:LpIWAOYPyDrXtU+BW7X0Yt/vGtYxtXQ8ql7dFfYUVZA= github.com/pion/datachannel v1.5.9/go.mod h1:kDUuk4CU4Uxp82NH4LQZbISULkX/HtzKa4P7ldf9izE= github.com/pion/dtls/v2 v2.0.0/go.mod h1:VkY5VL2wtsQQOG60xQ4lkV5pdn0wwBBTzCfRJqXhp3A= -github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= -github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= -github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= +github.com/pion/dtls/v3 v3.0.3 h1:j5ajZbQwff7Z8k3pE3S+rQ4STvKvXUdKsi/07ka+OWM= +github.com/pion/dtls/v3 v3.0.3/go.mod h1:weOTUyIV4z0bQaVzKe8kpaP17+us3yAuiQsEAG1STMU= github.com/pion/ice v0.7.13/go.mod h1:U3ERMkJgkPMlBjzMe2XxIQPl6ZrfRHyENwGCBoFrWWk= github.com/pion/ice v0.7.14/go.mod h1:/Lz6jAUhsvXed7kNJImXtvVSgjtcdGKoZAZIYb9WEm0= -github.com/pion/ice/v2 v2.3.36 h1:SopeXiVbbcooUg2EIR8sq4b13RQ8gzrkkldOVg+bBsc= -github.com/pion/ice/v2 v2.3.36/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ= +github.com/pion/ice/v4 v4.0.2 h1:1JhBRX8iQLi0+TfcavTjPjI6GO41MFn4CeTBX+Y9h5s= +github.com/pion/ice/v4 v4.0.2/go.mod h1:DCdqyzgtsDNYN6/3U8044j3U7qsJ9KFJC92VnOWHvXg= github.com/pion/interceptor v0.1.37 h1:aRA8Zpab/wE7/c0O3fh1PqY0AJI3fCSEM5lRWJVorwI= github.com/pion/interceptor v0.1.37/go.mod h1:JzxbJ4umVTlZAf+/utHzNesY8tmRkM2lVmkS82TTj8Y= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= github.com/pion/mdns v0.0.4/go.mod h1:R1sL0p50l42S5lJs91oNdUL58nm0QHrhxnSegr++qC0= -github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8= -github.com/pion/mdns v0.0.12/go.mod h1:VExJjv8to/6Wqm1FXK+Ii/Z9tsVk/F5sD/N70cnYFbk= +github.com/pion/mdns/v2 v2.0.7 h1:c9kM8ewCgjslaAmicYMFQIde2H9/lrZpjBkN8VwoVtM= +github.com/pion/mdns/v2 v2.0.7/go.mod h1:vAdSYNAT0Jy3Ru0zl2YiW3Rm/fJCwIeM0nToenfOJKA= github.com/pion/quic v0.1.1/go.mod h1:zEU51v7ru8Mp4AUBJvj6psrSth5eEFNnVQK5K48oV3k= github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= github.com/pion/rtcp v1.2.1/go.mod h1:a5dj2d6BKIKHl43EnAOIrCczcjESrtPuMgfmL6/K6QM= -github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE= github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= github.com/pion/rtp v1.3.2/go.mod h1:q9wPnA96pu2urCcW/sK/RiDn597bhGoAQQ+y2fDwHuY= github.com/pion/rtp v1.4.0/go.mod h1:/l4cvcKd0D3u9JLs2xSVI95YkfXW87a3br3nqmVtSlE= -github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= github.com/pion/rtp v1.8.9 h1:E2HX740TZKaqdcPmf4pw6ZZuG8u5RlMMt+l3dxeu6Wk= github.com/pion/rtp v1.8.9/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= github.com/pion/sctp v1.7.6/go.mod h1:ichkYQ5tlgCQwEwvgfdcAolqx1nHbYCxo4D7zK/K0X8= @@ -1020,33 +1016,23 @@ github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY= github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M= github.com/pion/srtp v1.3.1/go.mod h1:nxEytDDGTN+eNKJ1l5gzOCWQFuksgijorsSlgEjc40Y= github.com/pion/srtp v1.3.2/go.mod h1:snPrfN+gVpRBpmats49oxLWfcFB01eH1N9F+N7+dxKI= -github.com/pion/srtp/v2 v2.0.20 h1:HNNny4s+OUmG280ETrCdgFndp4ufx3/uy85EawYEhTk= -github.com/pion/srtp/v2 v2.0.20/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= +github.com/pion/srtp/v3 v3.0.4 h1:2Z6vDVxzrX3UHEgrUyIGM4rRouoC7v+NiF1IHtp9B5M= +github.com/pion/srtp/v3 v3.0.4/go.mod h1:1Jx3FwDoxpRaTh1oRV8A/6G1BnFL+QI82eK4ms8EEJQ= github.com/pion/stun v0.3.3/go.mod h1:xrCld6XM+6GWDZdvjPlLMsTU21rNxnO6UO8XsAvHr/M= -github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8= -github.com/pion/stun v0.6.2-0.20230901070932-d1f1ac894921 h1:F6QLRayjVgnYywFO+J0T7m/X8LpL66VXsyx/MnIdD/I= -github.com/pion/stun v0.6.2-0.20230901070932-d1f1ac894921/go.mod h1:TPtwLHxmnbYdWg6M2XActPlr3JEctqwaEem/wMh4AG4= +github.com/pion/stun/v3 v3.0.0 h1:4h1gwhWLWuZWOJIJR9s2ferRO+W3zA/b6ijOI6mKzUw= +github.com/pion/stun/v3 v3.0.0/go.mod h1:HvCN8txt8mwi4FBvS3EmDghW6aQJ24T+y+1TKjB5jyU= github.com/pion/transport v0.6.0/go.mod h1:iWZ07doqOosSLMhZ+FXUTq+TamDoXSllxpbGcfkCmbE= github.com/pion/transport v0.8.10/go.mod h1:tBmha/UCjpum5hqTWhfAEs3CO4/tHSg0MYRhSzR+CZ8= github.com/pion/transport v0.10.0/go.mod h1:BnHnUipd0rZQyTVB2SBGojFHT9CBt5C5TcsJSQGkvSE= -github.com/pion/transport v0.13.1 h1:/UH5yLeQtwm2VZIPjxwnNFxjS4DFhyLfS4GlfuKUzfA= -github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= -github.com/pion/transport/v2 v2.2.2/go.mod h1:OJg3ojoBJopjEeECq2yJdXH9YVrUJ1uQ++NjXLOUorc= -github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= -github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= -github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQpw6Q= -github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= -github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= github.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1o0= github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uPLGhhz9rwo= github.com/pion/turn/v2 v2.0.3/go.mod h1:kl1hmT3NxcLynpXVnwJgObL8C9NaCyPTeqI2DcCpSZs= -github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= -github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= +github.com/pion/turn/v4 v4.0.0 h1:qxplo3Rxa9Yg1xXDxxH8xaqcyGUtbHYw4QSCvmFWvhM= +github.com/pion/turn/v4 v4.0.0/go.mod h1:MuPDkm15nYSklKpN8vWJ9W2M0PlyQZqYt1McGuxG7mA= github.com/pion/webrtc/v2 v2.2.7/go.mod h1:EfCuvKjzMgX4F/aSryRUC7L9o3u2N8WNUgnzd6wOO+8= github.com/pion/webrtc/v2 v2.2.9/go.mod h1:TcArPDphZIBtZ+mh8J/qOREyY3ca7ihQrenulOIvfPQ= -github.com/pion/webrtc/v3 v3.3.4 h1:v2heQVnXTSqNRXcaFQVOhIOYkLMxOu1iJG8uy1djvkk= -github.com/pion/webrtc/v3 v3.3.4/go.mod h1:liNa+E1iwyzyXqNUwvoMRNQ10x8h8FOeJKL8RkIbamE= +github.com/pion/webrtc/v4 v4.0.0 h1:x8ec7uJQPP3D1iI8ojPAiTOylPI7Fa7QgqZrhpLyqZ8= +github.com/pion/webrtc/v4 v4.0.0/go.mod h1:SfNn8CcFxR6OUVjLXVslAQ3a3994JhyE3Hw1jAuqEto= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -1233,7 +1219,6 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= @@ -1269,8 +1254,8 @@ github.com/ucwong/filecache v1.0.6-0.20230405163841-810d53ced4bd h1:gBtlvLAsgLk+ github.com/ucwong/filecache v1.0.6-0.20230405163841-810d53ced4bd/go.mod h1:ddwX+NCjMZPdpzcGh1fcEbNTUTCtKgt2hC2rqvmLKgA= github.com/ucwong/go-ttlmap v1.0.2-0.20221020173635-331e7ddde2bb h1:dVZH3AH9f7zB3VBmsjn25B7lfcAyMP4QxdFYTrfj7tg= github.com/ucwong/go-ttlmap v1.0.2-0.20221020173635-331e7ddde2bb/go.mod h1:3yswsBsVuwsOjDvFfC5Na9XSEf4HC7mj3W3g6jvSY/s= -github.com/ucwong/golang-kv v1.0.24-0.20241010105424-84c909d0d763 h1:dqIoVCWsz7GHWSVhTIJfacbICsIY3hBSKuYhZJai0Do= -github.com/ucwong/golang-kv v1.0.24-0.20241010105424-84c909d0d763/go.mod h1:uzalpYzBhBf7dVztOVa0IezjObGxqpircHu/BkXIxk4= +github.com/ucwong/golang-kv v1.0.24-0.20241013181450-613f8dd1b92b h1:2eiyaBkmYYY0+s+IwckgSwcUDCD3Qu2nwzT2fzZMaIQ= +github.com/ucwong/golang-kv v1.0.24-0.20241013181450-613f8dd1b92b/go.mod h1:k6yN3QkR9aBfD34BOMDfBGU83WzXCPGCDVc+S5TBt1U= github.com/ucwong/golang-set v1.8.1-0.20200419153428-d7b0b1ac2d43/go.mod h1:xu0FaiQFGbBcFZj2o7udZ5rbA8jRTsv47hkPoG5qQNM= github.com/ucwong/goleveldb v1.0.3-0.20200508074755-578cba616f37/go.mod h1:dgJUTtDxq/ne6/JzZhHzF24OL/uqILz9IWk8HmT4V2g= github.com/ucwong/goleveldb v1.0.3-0.20200618184106-f1c6bc3a428b/go.mod h1:7Sq6w7AfEZuB/a6mrlvHCSXCSkqojCMMrM3Ei12QAT0= @@ -1285,8 +1270,8 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= -github.com/urfave/cli/v2 v2.27.4 h1:o1owoI+02Eb+K107p27wEX9Bb8eqIoZCfLXloLUSWJ8= -github.com/urfave/cli/v2 v2.27.4/go.mod h1:m4QzxcD2qpra4z7WhzEGn74WZLViBnMpb1ToCAKdGRQ= +github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w= +github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= @@ -1294,7 +1279,6 @@ github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPyS github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bloom v0.0.0-20170505221640-54e3b963ee16/go.mod h1:MmAltL9pDMNTrvUkxdg0k0q5I0suxmuwp3KbyrZLOZ8= github.com/willf/bloom v2.0.3+incompatible/go.mod h1:MmAltL9pDMNTrvUkxdg0k0q5I0suxmuwp3KbyrZLOZ8= -github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU= github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= @@ -1379,10 +1363,6 @@ golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= -golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= -golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1424,7 +1404,6 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180524181706-dfa909b99c79/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1480,13 +1459,7 @@ golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= -golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1509,7 +1482,6 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1588,23 +1560,12 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= -golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= -golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1615,10 +1576,6 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1669,7 +1626,6 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/vendor/github.com/anacrolix/torrent/client.go b/vendor/github.com/anacrolix/torrent/client.go index fe5c4fcced..acf5732ec1 100644 --- a/vendor/github.com/anacrolix/torrent/client.go +++ b/vendor/github.com/anacrolix/torrent/client.go @@ -34,7 +34,7 @@ import ( "github.com/dustin/go-humanize" gbtree "github.com/google/btree" "github.com/pion/datachannel" - "github.com/pion/webrtc/v3" + "github.com/pion/webrtc/v4" "github.com/anacrolix/torrent/bencode" "github.com/anacrolix/torrent/internal/check" diff --git a/vendor/github.com/anacrolix/torrent/config.go b/vendor/github.com/anacrolix/torrent/config.go index 9eb3444dda..76979463cc 100644 --- a/vendor/github.com/anacrolix/torrent/config.go +++ b/vendor/github.com/anacrolix/torrent/config.go @@ -11,7 +11,7 @@ import ( "github.com/anacrolix/dht/v2/krpc" "github.com/anacrolix/log" "github.com/anacrolix/missinggo/v2" - "github.com/pion/webrtc/v3" + "github.com/pion/webrtc/v4" "golang.org/x/time/rate" "github.com/anacrolix/torrent/iplist" diff --git a/vendor/github.com/anacrolix/torrent/torrent.go b/vendor/github.com/anacrolix/torrent/torrent.go index 7435c9b6c2..f8115f6562 100644 --- a/vendor/github.com/anacrolix/torrent/torrent.go +++ b/vendor/github.com/anacrolix/torrent/torrent.go @@ -33,7 +33,7 @@ import ( "github.com/anacrolix/multiless" "github.com/anacrolix/sync" "github.com/pion/datachannel" - "github.com/pion/webrtc/v3" + "github.com/pion/webrtc/v4" "golang.org/x/sync/errgroup" "github.com/anacrolix/torrent/bencode" diff --git a/vendor/github.com/anacrolix/torrent/webrtc.go b/vendor/github.com/anacrolix/torrent/webrtc.go index ca4f80fb9f..918159dbb7 100644 --- a/vendor/github.com/anacrolix/torrent/webrtc.go +++ b/vendor/github.com/anacrolix/torrent/webrtc.go @@ -6,7 +6,7 @@ import ( "time" "github.com/pion/datachannel" - "github.com/pion/webrtc/v3" + "github.com/pion/webrtc/v4" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" diff --git a/vendor/github.com/anacrolix/torrent/webtorrent/peer-conn-stats.go b/vendor/github.com/anacrolix/torrent/webtorrent/peer-conn-stats.go index 907398625f..fa4fbd19ea 100644 --- a/vendor/github.com/anacrolix/torrent/webtorrent/peer-conn-stats.go +++ b/vendor/github.com/anacrolix/torrent/webtorrent/peer-conn-stats.go @@ -4,7 +4,7 @@ package webtorrent import ( - "github.com/pion/webrtc/v3" + "github.com/pion/webrtc/v4" ) func GetPeerConnStats(pc *wrappedPeerConnection) (stats webrtc.StatsReport) { diff --git a/vendor/github.com/anacrolix/torrent/webtorrent/peer-conn-stats_js.go b/vendor/github.com/anacrolix/torrent/webtorrent/peer-conn-stats_js.go index 7f770b1d8b..9f8e4124a0 100644 --- a/vendor/github.com/anacrolix/torrent/webtorrent/peer-conn-stats_js.go +++ b/vendor/github.com/anacrolix/torrent/webtorrent/peer-conn-stats_js.go @@ -4,7 +4,7 @@ package webtorrent import ( - "github.com/pion/webrtc/v3" + "github.com/pion/webrtc/v4" ) // webrtc.PeerConnection.GetStats() is not currently supported for WASM. Return empty stats. diff --git a/vendor/github.com/anacrolix/torrent/webtorrent/setting-engine.go b/vendor/github.com/anacrolix/torrent/webtorrent/setting-engine.go index a84ee02044..65a4d4d6e3 100644 --- a/vendor/github.com/anacrolix/torrent/webtorrent/setting-engine.go +++ b/vendor/github.com/anacrolix/torrent/webtorrent/setting-engine.go @@ -8,7 +8,7 @@ import ( "io" "github.com/pion/logging" - "github.com/pion/webrtc/v3" + "github.com/pion/webrtc/v4" ) var s = webrtc.SettingEngine{ diff --git a/vendor/github.com/anacrolix/torrent/webtorrent/setting-engine_js.go b/vendor/github.com/anacrolix/torrent/webtorrent/setting-engine_js.go index ea42d11aec..c1916a6fd0 100644 --- a/vendor/github.com/anacrolix/torrent/webtorrent/setting-engine_js.go +++ b/vendor/github.com/anacrolix/torrent/webtorrent/setting-engine_js.go @@ -5,7 +5,7 @@ package webtorrent import ( - "github.com/pion/webrtc/v3" + "github.com/pion/webrtc/v4" ) // I'm not sure what to do for logging for JS. See diff --git a/vendor/github.com/anacrolix/torrent/webtorrent/tracker-client.go b/vendor/github.com/anacrolix/torrent/webtorrent/tracker-client.go index cc0c65849b..945097f30d 100644 --- a/vendor/github.com/anacrolix/torrent/webtorrent/tracker-client.go +++ b/vendor/github.com/anacrolix/torrent/webtorrent/tracker-client.go @@ -13,7 +13,7 @@ import ( "github.com/anacrolix/log" "github.com/gorilla/websocket" "github.com/pion/datachannel" - "github.com/pion/webrtc/v3" + "github.com/pion/webrtc/v4" "go.opentelemetry.io/otel/trace" "github.com/anacrolix/torrent/tracker" diff --git a/vendor/github.com/anacrolix/torrent/webtorrent/tracker-protocol.go b/vendor/github.com/anacrolix/torrent/webtorrent/tracker-protocol.go index 14be67e452..0fcdaf267b 100644 --- a/vendor/github.com/anacrolix/torrent/webtorrent/tracker-protocol.go +++ b/vendor/github.com/anacrolix/torrent/webtorrent/tracker-protocol.go @@ -4,7 +4,7 @@ import ( "fmt" "math" - "github.com/pion/webrtc/v3" + "github.com/pion/webrtc/v4" ) type AnnounceRequest struct { diff --git a/vendor/github.com/anacrolix/torrent/webtorrent/transport.go b/vendor/github.com/anacrolix/torrent/webtorrent/transport.go index 6231fd8d66..3dfc84ab90 100644 --- a/vendor/github.com/anacrolix/torrent/webtorrent/transport.go +++ b/vendor/github.com/anacrolix/torrent/webtorrent/transport.go @@ -11,7 +11,7 @@ import ( "github.com/anacrolix/log" "github.com/anacrolix/missinggo/v2/pproffd" "github.com/pion/datachannel" - "github.com/pion/webrtc/v3" + "github.com/pion/webrtc/v4" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" diff --git a/vendor/github.com/anacrolix/torrent/wstracker.go b/vendor/github.com/anacrolix/torrent/wstracker.go index 8952cc9475..7f53987bc9 100644 --- a/vendor/github.com/anacrolix/torrent/wstracker.go +++ b/vendor/github.com/anacrolix/torrent/wstracker.go @@ -11,7 +11,7 @@ import ( "github.com/anacrolix/log" "github.com/gorilla/websocket" "github.com/pion/datachannel" - "github.com/pion/webrtc/v3" + "github.com/pion/webrtc/v4" "github.com/anacrolix/torrent/tracker" httpTracker "github.com/anacrolix/torrent/tracker/http" diff --git a/vendor/github.com/getsentry/sentry-go/CHANGELOG.md b/vendor/github.com/getsentry/sentry-go/CHANGELOG.md index dce9a3ff97..4818085cf0 100644 --- a/vendor/github.com/getsentry/sentry-go/CHANGELOG.md +++ b/vendor/github.com/getsentry/sentry-go/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 0.29.1 + +The Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.29.1. + +### Bug Fixes + +- Correlate errors to the current trace ([#886](https://github.com/getsentry/sentry-go/pull/886)) +- Set the trace context when the transaction finishes ([#888](https://github.com/getsentry/sentry-go/pull/888)) + ## 0.29.0 The Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.29.0. diff --git a/vendor/github.com/getsentry/sentry-go/scope.go b/vendor/github.com/getsentry/sentry-go/scope.go index 48621c94fc..5be1c02e13 100644 --- a/vendor/github.com/getsentry/sentry-go/scope.go +++ b/vendor/github.com/getsentry/sentry-go/scope.go @@ -383,6 +383,15 @@ func (scope *Scope) ApplyToEvent(event *Event, hint *EventHint, client *Client) } for key, value := range scope.contexts { + if key == "trace" && event.Type == transactionType { + // Do not override trace context of + // transactions, otherwise it breaks the + // transaction event representation. + // For error events, the trace context is used + // to link errors and traces/spans in Sentry. + continue + } + // Ensure we are not overwriting event fields if _, ok := event.Contexts[key]; !ok { event.Contexts[key] = cloneContext(value) @@ -395,7 +404,9 @@ func (scope *Scope) ApplyToEvent(event *Event, hint *EventHint, client *Client) } if scope.span != nil { - event.Contexts["trace"] = scope.span.traceContext().Map() + if _, ok := event.Contexts["trace"]; !ok { + event.Contexts["trace"] = scope.span.traceContext().Map() + } transaction := scope.span.GetTransaction() if transaction != nil { diff --git a/vendor/github.com/getsentry/sentry-go/sentry.go b/vendor/github.com/getsentry/sentry-go/sentry.go index 0fca64e263..476eb178d9 100644 --- a/vendor/github.com/getsentry/sentry-go/sentry.go +++ b/vendor/github.com/getsentry/sentry-go/sentry.go @@ -6,7 +6,7 @@ import ( ) // The version of the SDK. -const SDKVersion = "0.29.0" +const SDKVersion = "0.29.1" // apiVersion is the minimum version of the Sentry API compatible with the // sentry-go SDK. diff --git a/vendor/github.com/getsentry/sentry-go/tracing.go b/vendor/github.com/getsentry/sentry-go/tracing.go index 0f5ade2e84..b30ceb79fd 100644 --- a/vendor/github.com/getsentry/sentry-go/tracing.go +++ b/vendor/github.com/getsentry/sentry-go/tracing.go @@ -195,6 +195,10 @@ func StartSpan(ctx context.Context, operation string, options ...SpanOption) *Sp clientOptions := span.clientOptions() if clientOptions.EnableTracing { hub := hubFromContext(ctx) + if !span.IsTransaction() { + // Push a new scope to stack for non transaction span + hub.PushScope() + } hub.Scope().SetSpan(&span) } @@ -355,6 +359,12 @@ func (s *Span) doFinish() { s.EndTime = monotonicTimeSince(s.StartTime) } + hub := hubFromContext(s.ctx) + if !s.IsTransaction() { + // Referenced to StartSpan function that pushes current non-transaction span to scope stack + defer hub.PopScope() + } + if !s.Sampled.Bool() { return } @@ -370,7 +380,6 @@ func (s *Span) doFinish() { // TODO(tracing): add breadcrumbs // (see https://github.com/getsentry/sentry-python/blob/f6f3525f8812f609/sentry_sdk/tracing.py#L372) - hub := hubFromContext(s.ctx) hub.CaptureEvent(event) } @@ -554,10 +563,11 @@ func (s *Span) toEvent() *Event { s.dynamicSamplingContext = DynamicSamplingContextFromTransaction(s) } - contexts := make(map[string]Context, len(s.contexts)) + contexts := make(map[string]Context, len(s.contexts)+1) for k, v := range s.contexts { contexts[k] = cloneContext(v) } + contexts["trace"] = s.traceContext().Map() // Make sure that the transaction source is valid transactionSource := s.Source diff --git a/vendor/github.com/pion/dtls/v2/AUTHORS.txt b/vendor/github.com/pion/dtls/v2/AUTHORS.txt deleted file mode 100644 index e14fae4c08..0000000000 --- a/vendor/github.com/pion/dtls/v2/AUTHORS.txt +++ /dev/null @@ -1,57 +0,0 @@ -# Thank you to everyone that made Pion possible. If you are interested in contributing -# we would love to have you https://github.com/pion/webrtc/wiki/Contributing -# -# This file is auto generated, using git to list all individuals contributors. -# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting -Aleksandr Razumov -alvarowolfx -Arlo Breault -Atsushi Watanabe -backkem -bjdgyc -boks1971 -Bragadeesh -Carson Hoffman -Cecylia Bocovich -Chris Hiszpanski -cnderrauber -Daniele Sluijters -folbrich -Hayden James -Hugo Arregui -Hugo Arregui -igolaizola <11333576+igolaizola@users.noreply.github.com> -Jeffrey Stoke -Jeroen de Bruijn -Jeroen de Bruijn -Jim Wert -jinleileiking -Jozef Kralik -Julien Salleyron -Juliusz Chroboczek -Kegan Dougal -Kevin Wang -Lander Noterman -Len -Lukas Lihotzki -ManuelBk <26275612+ManuelBk@users.noreply.github.com> -Michael Zabka -Michiel De Backker -Rachel Chen -Robert Eperjesi -Ryan Gordon -Sam Lancia -Sean DuBois -Sean DuBois -Sean DuBois -Shelikhoo -Stefan Tatschner -Steffen Vogel -Vadim -Vadim Filimonov -wmiao -ZHENK -吕海涛 - -# List of contributors not appearing in Git history - diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/errors.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/errors.go deleted file mode 100644 index c5e954ce5a..0000000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/errors.go +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package extension - -import ( - "errors" - - "github.com/pion/dtls/v2/pkg/protocol" -) - -var ( - // ErrALPNInvalidFormat is raised when the ALPN format is invalid - ErrALPNInvalidFormat = &protocol.FatalError{Err: errors.New("invalid alpn format")} //nolint:goerr113 - errALPNNoAppProto = &protocol.FatalError{Err: errors.New("no application protocol")} //nolint:goerr113 - errBufferTooSmall = &protocol.TemporaryError{Err: errors.New("buffer is too small")} //nolint:goerr113 - errInvalidExtensionType = &protocol.FatalError{Err: errors.New("invalid extension type")} //nolint:goerr113 - errInvalidSNIFormat = &protocol.FatalError{Err: errors.New("invalid server name format")} //nolint:goerr113 - errLengthMismatch = &protocol.InternalError{Err: errors.New("data length and declared length do not match")} //nolint:goerr113 -) diff --git a/vendor/github.com/pion/dtls/v2/resume.go b/vendor/github.com/pion/dtls/v2/resume.go deleted file mode 100644 index f070d75373..0000000000 --- a/vendor/github.com/pion/dtls/v2/resume.go +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import ( - "context" - "net" -) - -// Resume imports an already established dtls connection using a specific dtls state -func Resume(state *State, conn net.Conn, config *Config) (*Conn, error) { - if err := state.initCipherSuite(); err != nil { - return nil, err - } - dconn, err := createConn(conn, config, state.isClient) - if err != nil { - return nil, err - } - c, err := handshakeConn(context.Background(), dconn, config, state.isClient, state) - if err != nil { - return nil, err - } - - return c, nil -} diff --git a/vendor/github.com/pion/dtls/v2/.editorconfig b/vendor/github.com/pion/dtls/v3/.editorconfig similarity index 100% rename from vendor/github.com/pion/dtls/v2/.editorconfig rename to vendor/github.com/pion/dtls/v3/.editorconfig diff --git a/vendor/github.com/pion/dtls/v2/.gitignore b/vendor/github.com/pion/dtls/v3/.gitignore similarity index 100% rename from vendor/github.com/pion/dtls/v2/.gitignore rename to vendor/github.com/pion/dtls/v3/.gitignore diff --git a/vendor/github.com/pion/srtp/v2/.golangci.yml b/vendor/github.com/pion/dtls/v3/.golangci.yml similarity index 91% rename from vendor/github.com/pion/srtp/v2/.golangci.yml rename to vendor/github.com/pion/dtls/v3/.golangci.yml index 4e3eddf429..a3235bec28 100644 --- a/vendor/github.com/pion/srtp/v2/.golangci.yml +++ b/vendor/github.com/pion/dtls/v3/.golangci.yml @@ -1,9 +1,13 @@ # SPDX-FileCopyrightText: 2023 The Pion community # SPDX-License-Identifier: MIT +run: + timeout: 5m + linters-settings: govet: - check-shadowing: true + enable: + - shadow misspell: locale: US exhaustive: @@ -29,7 +33,6 @@ linters: - bodyclose # checks whether HTTP response body is closed successfully - contextcheck # check the function whether use a non-inherited context - decorder # check declaration order and count of types, constants, variables and functions - - depguard # Go linter that checks if package imports are in a list of acceptable packages - dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) - dupl # Tool for code clone detection - durationcheck # check for two durations multiplied together @@ -48,7 +51,7 @@ linters: - goconst # Finds repeated strings that could be replaced by a constant - gocritic # The most opinionated Go source code linter - godox # Tool for detection of FIXME, TODO and other comment keywords - - goerr113 # Golang linter to check the errors handling expressions + - err113 # Golang linter to check the errors handling expressions - gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification - gofumpt # Gofumpt checks whether code was gofumpt-ed. - goheader # Checks is file header matches to pattern @@ -63,7 +66,6 @@ linters: - importas # Enforces consistent import aliases - ineffassign # Detects when assignments to existing variables are not used - misspell # Finds commonly misspelled English words in comments - - nakedret # Finds naked returns in functions greater than a specified function length - nilerr # Finds the code that returns nil even if it checks that the error is not nil. - nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. - noctx # noctx finds sending http request without context.Context @@ -81,19 +83,18 @@ linters: - wastedassign # wastedassign finds wasted assignment statements - whitespace # Tool for detection of leading and trailing whitespace disable: + - depguard # Go linter that checks if package imports are in a list of acceptable packages - containedctx # containedctx is a linter that detects struct contained context.Context field - cyclop # checks function and package cyclomatic complexity - - exhaustivestruct # Checks if all struct's fields are initialized - funlen # Tool for detection of long functions - gocyclo # Computes and checks the cyclomatic complexity of functions - godot # Check if comments end in a period - gomnd # An analyzer to detect magic numbers. - - ifshort # Checks that your code uses short syntax for if-statements whenever possible - ireturn # Accept Interfaces, Return Concrete Types - lll # Reports long lines - maintidx # maintidx measures the maintainability index of each function. - makezero # Finds slice declarations with non-zero initial length - - maligned # Tool to detect Go structs that would take less memory if their fields were sorted + - nakedret # Finds naked returns in functions greater than a specified function length - nestif # Reports deeply nested if statements - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity - nolintlint # Reports ill-formed or insufficient nolint directives @@ -110,28 +111,15 @@ linters: issues: exclude-use-default: false + exclude-dirs-use-default: false exclude-rules: - # Allow complex tests, better to be self contained - - path: _test\.go + # Allow complex tests and examples, better to be self contained + - path: (examples|main\.go|_test\.go) linters: - - gocognit - forbidigo - - # Allow complex main function in examples - - path: examples - text: "of func `main` is high" - linters: - gocognit - - # Allow forbidden identifiers in examples - - path: examples - linters: - - forbidigo # Allow forbidden identifiers in CLI commands - path: cmd linters: - forbidigo - -run: - skip-dirs-use-default: false diff --git a/vendor/github.com/pion/dtls/v2/.goreleaser.yml b/vendor/github.com/pion/dtls/v3/.goreleaser.yml similarity index 100% rename from vendor/github.com/pion/dtls/v2/.goreleaser.yml rename to vendor/github.com/pion/dtls/v3/.goreleaser.yml diff --git a/vendor/github.com/pion/dtls/v2/LICENSE b/vendor/github.com/pion/dtls/v3/LICENSE similarity index 100% rename from vendor/github.com/pion/dtls/v2/LICENSE rename to vendor/github.com/pion/dtls/v3/LICENSE diff --git a/vendor/github.com/pion/dtls/v2/README.md b/vendor/github.com/pion/dtls/v3/README.md similarity index 95% rename from vendor/github.com/pion/dtls/v2/README.md rename to vendor/github.com/pion/dtls/v3/README.md index 0c0659593b..fa00c95d85 100644 --- a/vendor/github.com/pion/dtls/v2/README.md +++ b/vendor/github.com/pion/dtls/v3/README.md @@ -10,9 +10,9 @@ Slack Widget
GitHub Workflow Status - Go Reference + Go Reference Coverage Status - Go Report Card + Go Report Card License: MIT


@@ -145,7 +145,7 @@ We are always looking to support **your projects**. Please reach out if you have If you need commercial support or don't want to use public methods you can contact us at [team@pion.ly](mailto:team@pion.ly) ### Contributing -Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible: [AUTHORS.txt](./AUTHORS.txt) +Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible ### License MIT License - see [LICENSE](LICENSE) for full text diff --git a/vendor/github.com/pion/dtls/v2/certificate.go b/vendor/github.com/pion/dtls/v3/certificate.go similarity index 96% rename from vendor/github.com/pion/dtls/v2/certificate.go rename to vendor/github.com/pion/dtls/v3/certificate.go index 519fc875f5..7e184dfd50 100644 --- a/vendor/github.com/pion/dtls/v2/certificate.go +++ b/vendor/github.com/pion/dtls/v3/certificate.go @@ -9,6 +9,8 @@ import ( "crypto/x509" "fmt" "strings" + + "github.com/pion/dtls/v3/pkg/protocol/handshake" ) // ClientHelloInfo contains information from a ClientHello message in order to @@ -22,6 +24,9 @@ type ClientHelloInfo struct { // CipherSuites lists the CipherSuites supported by the client (e.g. // TLS_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256). CipherSuites []CipherSuiteID + + // RandomBytes stores the client hello random bytes + RandomBytes [handshake.RandomBytesLength]byte } // CertificateRequestInfo contains information from a server's diff --git a/vendor/github.com/pion/dtls/v2/cipher_suite.go b/vendor/github.com/pion/dtls/v3/cipher_suite.go similarity index 97% rename from vendor/github.com/pion/dtls/v2/cipher_suite.go rename to vendor/github.com/pion/dtls/v3/cipher_suite.go index 7a5bb4a585..af95dec2ea 100644 --- a/vendor/github.com/pion/dtls/v2/cipher_suite.go +++ b/vendor/github.com/pion/dtls/v3/cipher_suite.go @@ -11,9 +11,9 @@ import ( "fmt" "hash" - "github.com/pion/dtls/v2/internal/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" + "github.com/pion/dtls/v3/internal/ciphersuite" + "github.com/pion/dtls/v3/pkg/crypto/clientcertificate" + "github.com/pion/dtls/v3/pkg/protocol/recordlayer" ) // CipherSuiteID is an ID for our supported CipherSuites @@ -95,7 +95,7 @@ type CipherSuite interface { Init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error IsInitialized() bool Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) - Decrypt(in []byte) ([]byte, error) + Decrypt(h recordlayer.Header, in []byte) ([]byte, error) } // CipherSuiteName provides the same functionality as tls.CipherSuiteName diff --git a/vendor/github.com/pion/dtls/v2/cipher_suite_go114.go b/vendor/github.com/pion/dtls/v3/cipher_suite_go114.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/cipher_suite_go114.go rename to vendor/github.com/pion/dtls/v3/cipher_suite_go114.go diff --git a/vendor/github.com/pion/dtls/v2/codecov.yml b/vendor/github.com/pion/dtls/v3/codecov.yml similarity index 100% rename from vendor/github.com/pion/dtls/v2/codecov.yml rename to vendor/github.com/pion/dtls/v3/codecov.yml diff --git a/vendor/github.com/pion/dtls/v2/compression_method.go b/vendor/github.com/pion/dtls/v3/compression_method.go similarity index 83% rename from vendor/github.com/pion/dtls/v2/compression_method.go rename to vendor/github.com/pion/dtls/v3/compression_method.go index 7e44de0092..49b11c7185 100644 --- a/vendor/github.com/pion/dtls/v2/compression_method.go +++ b/vendor/github.com/pion/dtls/v3/compression_method.go @@ -3,7 +3,7 @@ package dtls -import "github.com/pion/dtls/v2/pkg/protocol" +import "github.com/pion/dtls/v3/pkg/protocol" func defaultCompressionMethods() []*protocol.CompressionMethod { return []*protocol.CompressionMethod{ diff --git a/vendor/github.com/pion/dtls/v2/config.go b/vendor/github.com/pion/dtls/v3/config.go similarity index 73% rename from vendor/github.com/pion/dtls/v2/config.go rename to vendor/github.com/pion/dtls/v3/config.go index fbc3ee2476..54a86c0ee4 100644 --- a/vendor/github.com/pion/dtls/v2/config.go +++ b/vendor/github.com/pion/dtls/v3/config.go @@ -4,16 +4,17 @@ package dtls import ( - "context" "crypto/ecdsa" "crypto/ed25519" "crypto/rsa" "crypto/tls" "crypto/x509" "io" + "net" "time" - "github.com/pion/dtls/v2/pkg/crypto/elliptic" + "github.com/pion/dtls/v3/pkg/crypto/elliptic" + "github.com/pion/dtls/v3/pkg/protocol/handshake" "github.com/pion/logging" ) @@ -44,6 +45,10 @@ type Config struct { // Servers will assert that clients send one of these profiles and will respond as needed SRTPProtectionProfiles []SRTPProtectionProfile + // SRTPMasterKeyIdentifier value (if any) is sent via the use_srtp + // extension for Clients and Servers + SRTPMasterKeyIdentifier []byte + // ClientAuth determines the server's policy for // TLS Client Authentication. The default is NoClientCert. ClientAuth ClientAuthType @@ -56,6 +61,10 @@ type Config struct { // defaults to time.Second FlightInterval time.Duration + // DisableRetransmitBackoff can be used to the disable the backoff feature + // when sending outbound messages as specified in RFC 4347 4.2.4.1 + DisableRetransmitBackoff bool + // PSK sets the pre-shared key used by this DTLS connection // If PSK is non-nil only PSK CipherSuites will be used PSK PSKCallback @@ -112,15 +121,6 @@ type Config struct { LoggerFactory logging.LoggerFactory - // ConnectContextMaker is a function to make a context used in Dial(), - // Client(), Server(), and Accept(). If nil, the default ConnectContextMaker - // is used. It can be implemented as following. - // - // func ConnectContextMaker() (context.Context, func()) { - // return context.WithTimeout(context.Background(), 30*time.Second) - // } - ConnectContextMaker func() (context.Context, func()) - // MTU is the length at which handshake messages will be fragmented to // fit within the maximum transmission unit (default is 1200 bytes) MTU int @@ -176,17 +176,52 @@ type Config struct { // skip hello verify phase and receive ServerHello after initial ClientHello. // This have implication on DoS attack resistance. InsecureSkipVerifyHello bool -} - -func defaultConnectContextMaker() (context.Context, func()) { - return context.WithTimeout(context.Background(), 30*time.Second) -} -func (c *Config) connectContextMaker() (context.Context, func()) { - if c.ConnectContextMaker == nil { - return defaultConnectContextMaker() - } - return c.ConnectContextMaker() + // ConnectionIDGenerator generates connection identifiers that should be + // sent by the remote party if it supports the DTLS Connection Identifier + // extension, as determined during the handshake. Generated connection + // identifiers must always have the same length. Returning a zero-length + // connection identifier indicates that the local party supports sending + // connection identifiers but does not require the remote party to send + // them. A nil ConnectionIDGenerator indicates that connection identifiers + // are not supported. + // https://datatracker.ietf.org/doc/html/rfc9146 + ConnectionIDGenerator func() []byte + + // PaddingLengthGenerator generates the number of padding bytes used to + // inflate ciphertext size in order to obscure content size from observers. + // The length of the content is passed to the generator such that both + // deterministic and random padding schemes can be applied while not + // exceeding maximum record size. + // If no PaddingLengthGenerator is specified, padding will not be applied. + // https://datatracker.ietf.org/doc/html/rfc9146#section-4 + PaddingLengthGenerator func(uint) uint + + // HelloRandomBytesGenerator generates custom client hello random bytes. + HelloRandomBytesGenerator func() [handshake.RandomBytesLength]byte + + // Handshake hooks: hooks can be used for testing invalid messages, + // mimicking other implementations or randomizing fields, which is valuable + // for applications that need censorship-resistance by making + // fingerprinting more difficult. + + // ClientHelloMessageHook, if not nil, is called when a Client Hello message is sent + // from a client. The returned handshake message replaces the original message. + ClientHelloMessageHook func(handshake.MessageClientHello) handshake.Message + + // ServerHelloMessageHook, if not nil, is called when a Server Hello message is sent + // from a server. The returned handshake message replaces the original message. + ServerHelloMessageHook func(handshake.MessageServerHello) handshake.Message + + // CertificateRequestMessageHook, if not nil, is called when a Certificate Request + // message is sent from a server. The returned handshake message replaces the original message. + CertificateRequestMessageHook func(handshake.MessageCertificateRequest) handshake.Message + + // OnConnectionAttempt is fired Whenever a connection attempt is made, the server or application can call this callback function. + // The callback function can then implement logic to handle the connection attempt, such as logging the attempt, + // checking against a list of blocked IPs, or counting the attempts to prevent brute force attacks. + // If the callback function returns an error, the connection attempt will be aborted. + OnConnectionAttempt func(net.Addr) error } func (c *Config) includeCertificateSuites() bool { diff --git a/vendor/github.com/pion/dtls/v2/conn.go b/vendor/github.com/pion/dtls/v3/conn.go similarity index 58% rename from vendor/github.com/pion/dtls/v2/conn.go rename to vendor/github.com/pion/dtls/v3/conn.go index ccea999d92..26c56f2e00 100644 --- a/vendor/github.com/pion/dtls/v2/conn.go +++ b/vendor/github.com/pion/dtls/v3/conn.go @@ -4,6 +4,7 @@ package dtls import ( + "bytes" "context" "errors" "fmt" @@ -13,17 +14,17 @@ import ( "sync/atomic" "time" - "github.com/pion/dtls/v2/internal/closer" - "github.com/pion/dtls/v2/pkg/crypto/elliptic" - "github.com/pion/dtls/v2/pkg/crypto/signaturehash" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/alert" - "github.com/pion/dtls/v2/pkg/protocol/handshake" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" + "github.com/pion/dtls/v3/internal/closer" + "github.com/pion/dtls/v3/pkg/crypto/elliptic" + "github.com/pion/dtls/v3/pkg/crypto/signaturehash" + "github.com/pion/dtls/v3/pkg/protocol" + "github.com/pion/dtls/v3/pkg/protocol/alert" + "github.com/pion/dtls/v3/pkg/protocol/handshake" + "github.com/pion/dtls/v3/pkg/protocol/recordlayer" "github.com/pion/logging" - "github.com/pion/transport/v2/connctx" - "github.com/pion/transport/v2/deadline" - "github.com/pion/transport/v2/replaydetector" + "github.com/pion/transport/v3/deadline" + "github.com/pion/transport/v3/netctx" + "github.com/pion/transport/v3/replaydetector" ) const ( @@ -48,26 +49,38 @@ func invalidKeyingLabels() map[string]bool { } } +type addrPkt struct { + rAddr net.Addr + data []byte +} + +type recvHandshakeState struct { + done chan struct{} + isRetransmit bool +} + // Conn represents a DTLS connection type Conn struct { - lock sync.RWMutex // Internal lock (must not be public) - nextConn connctx.ConnCtx // Embedded Conn, typically a udpconn we read/write from - fragmentBuffer *fragmentBuffer // out-of-order and missing fragment handling - handshakeCache *handshakeCache // caching of handshake messages for verifyData generation - decrypted chan interface{} // Decrypted Application Data or error, pull by calling `Read` - - state State // Internal state + lock sync.RWMutex // Internal lock (must not be public) + nextConn netctx.PacketConn // Embedded Conn, typically a udpconn we read/write from + fragmentBuffer *fragmentBuffer // out-of-order and missing fragment handling + handshakeCache *handshakeCache // caching of handshake messages for verifyData generation + decrypted chan interface{} // Decrypted Application Data or error, pull by calling `Read` + rAddr net.Addr + state State // Internal state maximumTransmissionUnit int + paddingLengthGenerator func(uint) uint handshakeCompletedSuccessfully atomic.Value + handshakeMutex sync.Mutex + handshakeDone chan struct{} - encryptedPackets [][]byte + encryptedPackets []addrPkt connectionClosedByUser bool closeLock sync.Mutex closed *closer.Closer - handshakeLoopsFinished sync.WaitGroup readDeadline *deadline.Deadline writeDeadline *deadline.Deadline @@ -75,18 +88,19 @@ type Conn struct { log logging.LeveledLogger reading chan struct{} - handshakeRecv chan chan struct{} + handshakeRecv chan recvHandshakeState cancelHandshaker func() cancelHandshakeReader func() fsm *handshakeFSM replayProtectionWindow uint + + handshakeConfig *handshakeConfig } -func createConn(nextConn net.Conn, config *Config, isClient bool) (*Conn, error) { - err := validateConfig(config) - if err != nil { +func createConn(nextConn net.PacketConn, rAddr net.Addr, config *Config, isClient bool, resumeState *State) (*Conn, error) { + if err := validateConfig(config); err != nil { return nil, err } @@ -111,38 +125,9 @@ func createConn(nextConn net.Conn, config *Config, isClient bool) (*Conn, error) replayProtectionWindow = defaultReplayProtectionWindow } - c := &Conn{ - nextConn: connctx.New(nextConn), - fragmentBuffer: newFragmentBuffer(), - handshakeCache: newHandshakeCache(), - maximumTransmissionUnit: mtu, - - decrypted: make(chan interface{}, 1), - log: logger, - - readDeadline: deadline.New(), - writeDeadline: deadline.New(), - - reading: make(chan struct{}, 1), - handshakeRecv: make(chan chan struct{}), - closed: closer.NewCloser(), - cancelHandshaker: func() {}, - - replayProtectionWindow: uint(replayProtectionWindow), - - state: State{ - isClient: isClient, - }, - } - - c.setRemoteEpoch(0) - c.setLocalEpoch(0) - return c, nil -} - -func handshakeConn(ctx context.Context, conn *Conn, config *Config, isClient bool, initialState *State) (*Conn, error) { - if conn == nil { - return nil, errNilNextConn + paddingLengthGenerator := config.PaddingLengthGenerator + if paddingLengthGenerator == nil { + paddingLengthGenerator = func(uint) uint { return 0 } } cipherSuites, err := parseCipherSuites(config.CipherSuites, config.CustomCipherSuites, config.includeCertificateSuites(), config.PSK != nil) @@ -172,59 +157,136 @@ func handshakeConn(ctx context.Context, conn *Conn, config *Config, isClient boo curves = defaultCurves } - hsCfg := &handshakeConfig{ - localPSKCallback: config.PSK, - localPSKIdentityHint: config.PSKIdentityHint, - localCipherSuites: cipherSuites, - localSignatureSchemes: signatureSchemes, - extendedMasterSecret: config.ExtendedMasterSecret, - localSRTPProtectionProfiles: config.SRTPProtectionProfiles, - serverName: serverName, - supportedProtocols: config.SupportedProtocols, - clientAuth: config.ClientAuth, - localCertificates: config.Certificates, - insecureSkipVerify: config.InsecureSkipVerify, - verifyPeerCertificate: config.VerifyPeerCertificate, - verifyConnection: config.VerifyConnection, - rootCAs: config.RootCAs, - clientCAs: config.ClientCAs, - customCipherSuites: config.CustomCipherSuites, - retransmitInterval: workerInterval, - log: conn.log, - initialEpoch: 0, - keyLogWriter: config.KeyLogWriter, - sessionStore: config.SessionStore, - ellipticCurves: curves, - localGetCertificate: config.GetCertificate, - localGetClientCertificate: config.GetClientCertificate, - insecureSkipHelloVerify: config.InsecureSkipVerifyHello, + handshakeConfig := &handshakeConfig{ + localPSKCallback: config.PSK, + localPSKIdentityHint: config.PSKIdentityHint, + localCipherSuites: cipherSuites, + localSignatureSchemes: signatureSchemes, + extendedMasterSecret: config.ExtendedMasterSecret, + localSRTPProtectionProfiles: config.SRTPProtectionProfiles, + localSRTPMasterKeyIdentifier: config.SRTPMasterKeyIdentifier, + serverName: serverName, + supportedProtocols: config.SupportedProtocols, + clientAuth: config.ClientAuth, + localCertificates: config.Certificates, + insecureSkipVerify: config.InsecureSkipVerify, + verifyPeerCertificate: config.VerifyPeerCertificate, + verifyConnection: config.VerifyConnection, + rootCAs: config.RootCAs, + clientCAs: config.ClientCAs, + customCipherSuites: config.CustomCipherSuites, + initialRetransmitInterval: workerInterval, + disableRetransmitBackoff: config.DisableRetransmitBackoff, + log: logger, + initialEpoch: 0, + keyLogWriter: config.KeyLogWriter, + sessionStore: config.SessionStore, + ellipticCurves: curves, + localGetCertificate: config.GetCertificate, + localGetClientCertificate: config.GetClientCertificate, + insecureSkipHelloVerify: config.InsecureSkipVerifyHello, + connectionIDGenerator: config.ConnectionIDGenerator, + helloRandomBytesGenerator: config.HelloRandomBytesGenerator, + clientHelloMessageHook: config.ClientHelloMessageHook, + serverHelloMessageHook: config.ServerHelloMessageHook, + certificateRequestMessageHook: config.CertificateRequestMessageHook, + resumeState: resumeState, } + c := &Conn{ + rAddr: rAddr, + nextConn: netctx.NewPacketConn(nextConn), + handshakeConfig: handshakeConfig, + fragmentBuffer: newFragmentBuffer(), + handshakeCache: newHandshakeCache(), + maximumTransmissionUnit: mtu, + paddingLengthGenerator: paddingLengthGenerator, + + decrypted: make(chan interface{}, 1), + log: logger, + + readDeadline: deadline.New(), + writeDeadline: deadline.New(), + + reading: make(chan struct{}, 1), + handshakeRecv: make(chan recvHandshakeState), + closed: closer.NewCloser(), + cancelHandshaker: func() {}, + cancelHandshakeReader: func() {}, + + replayProtectionWindow: uint(replayProtectionWindow), + + state: State{ + isClient: isClient, + }, + } + + c.setRemoteEpoch(0) + c.setLocalEpoch(0) + return c, nil +} + +// Handshake runs the client or server DTLS handshake +// protocol if it has not yet been run. +// +// Most uses of this package need not call Handshake explicitly: the +// first [Conn.Read] or [Conn.Write] will call it automatically. +// +// For control over canceling or setting a timeout on a handshake, use +// [Conn.HandshakeContext]. +func (c *Conn) Handshake() error { + return c.HandshakeContext(context.Background()) +} + +// HandshakeContext runs the client or server DTLS handshake +// protocol if it has not yet been run. +// +// The provided Context must be non-nil. If the context is canceled before +// the handshake is complete, the handshake is interrupted and an error is returned. +// Once the handshake has completed, cancellation of the context will not affect the +// connection. +// +// Most uses of this package need not call HandshakeContext explicitly: the +// first [Conn.Read] or [Conn.Write] will call it automatically. +func (c *Conn) HandshakeContext(ctx context.Context) error { + c.handshakeMutex.Lock() + defer c.handshakeMutex.Unlock() + + if c.isHandshakeCompletedSuccessfully() { + return nil + } + + handshakeDone := make(chan struct{}) + defer close(handshakeDone) + c.closeLock.Lock() + c.handshakeDone = handshakeDone + c.closeLock.Unlock() + // rfc5246#section-7.4.3 // In addition, the hash and signature algorithms MUST be compatible // with the key in the server's end-entity certificate. - if !isClient { - cert, err := hsCfg.getCertificate(&ClientHelloInfo{}) + if !c.state.isClient { + cert, err := c.handshakeConfig.getCertificate(&ClientHelloInfo{}) if err != nil && !errors.Is(err, errNoCertificates) { - return nil, err + return err } - hsCfg.localCipherSuites = filterCipherSuitesForCertificate(cert, cipherSuites) + c.handshakeConfig.localCipherSuites = filterCipherSuitesForCertificate(cert, c.handshakeConfig.localCipherSuites) } var initialFlight flightVal var initialFSMState handshakeState - if initialState != nil { - if conn.state.isClient { + if c.handshakeConfig.resumeState != nil { + if c.state.isClient { initialFlight = flight5 } else { initialFlight = flight6 } initialFSMState = handshakeFinished - conn.state = *initialState + c.state = *c.handshakeConfig.resumeState } else { - if conn.state.isClient { + if c.state.isClient { initialFlight = flight1 } else { initialFlight = flight0 @@ -232,56 +294,30 @@ func handshakeConn(ctx context.Context, conn *Conn, config *Config, isClient boo initialFSMState = handshakePreparing } // Do handshake - if err := conn.handshake(ctx, hsCfg, initialFlight, initialFSMState); err != nil { - return nil, err + if err := c.handshake(ctx, c.handshakeConfig, initialFlight, initialFSMState); err != nil { + return err } - conn.log.Trace("Handshake Completed") + c.log.Trace("Handshake Completed") - return conn, nil + return nil } // Dial connects to the given network address and establishes a DTLS connection on top. -// Connection handshake will timeout using ConnectContextMaker in the Config. -// If you want to specify the timeout duration, use DialWithContext() instead. -func Dial(network string, raddr *net.UDPAddr, config *Config) (*Conn, error) { - ctx, cancel := config.connectContextMaker() - defer cancel() - - return DialWithContext(ctx, network, raddr, config) -} - -// Client establishes a DTLS connection over an existing connection. -// Connection handshake will timeout using ConnectContextMaker in the Config. -// If you want to specify the timeout duration, use ClientWithContext() instead. -func Client(conn net.Conn, config *Config) (*Conn, error) { - ctx, cancel := config.connectContextMaker() - defer cancel() - - return ClientWithContext(ctx, conn, config) -} - -// Server listens for incoming DTLS connections. -// Connection handshake will timeout using ConnectContextMaker in the Config. -// If you want to specify the timeout duration, use ServerWithContext() instead. -func Server(conn net.Conn, config *Config) (*Conn, error) { - ctx, cancel := config.connectContextMaker() - defer cancel() - - return ServerWithContext(ctx, conn, config) -} - -// DialWithContext connects to the given network address and establishes a DTLS connection on top. -func DialWithContext(ctx context.Context, network string, raddr *net.UDPAddr, config *Config) (*Conn, error) { - pConn, err := net.DialUDP(network, nil, raddr) +func Dial(network string, rAddr *net.UDPAddr, config *Config) (*Conn, error) { + // net.ListenUDP is used rather than net.DialUDP as the latter prevents the + // use of net.PacketConn.WriteTo. + // https://github.com/golang/go/blob/ce5e37ec21442c6eb13a43e68ca20129102ebac0/src/net/udpsock_posix.go#L115 + pConn, err := net.ListenUDP(network, nil) if err != nil { return nil, err } - return ClientWithContext(ctx, pConn, config) + + return Client(pConn, rAddr, config) } -// ClientWithContext establishes a DTLS connection over an existing connection. -func ClientWithContext(ctx context.Context, conn net.Conn, config *Config) (*Conn, error) { +// Client establishes a DTLS connection over an existing connection. +func Client(conn net.PacketConn, rAddr net.Addr, config *Config) (*Conn, error) { switch { case config == nil: return nil, errNoConfigProvided @@ -289,30 +325,26 @@ func ClientWithContext(ctx context.Context, conn net.Conn, config *Config) (*Con return nil, errPSKAndIdentityMustBeSetForClient } - dconn, err := createConn(conn, config, true) - if err != nil { - return nil, err - } - - return handshakeConn(ctx, dconn, config, true, nil) + return createConn(conn, rAddr, config, true, nil) } -// ServerWithContext listens for incoming DTLS connections. -func ServerWithContext(ctx context.Context, conn net.Conn, config *Config) (*Conn, error) { +// Server listens for incoming DTLS connections. +func Server(conn net.PacketConn, rAddr net.Addr, config *Config) (*Conn, error) { if config == nil { return nil, errNoConfigProvided } - dconn, err := createConn(conn, config, false) - if err != nil { - return nil, err + if config.OnConnectionAttempt != nil { + if err := config.OnConnectionAttempt(rAddr); err != nil { + return nil, err + } } - return handshakeConn(ctx, dconn, config, false, nil) + return createConn(conn, rAddr, config, false, nil) } // Read reads data from the connection. func (c *Conn) Read(p []byte) (n int, err error) { - if !c.isHandshakeCompletedSuccessfully() { - return 0, errHandshakeInProgress + if err := c.Handshake(); err != nil { + return 0, err } select { @@ -355,8 +387,8 @@ func (c *Conn) Write(p []byte) (int, error) { default: } - if !c.isHandshakeCompletedSuccessfully() { - return 0, errHandshakeInProgress + if err := c.Handshake(); err != nil { + return 0, err } return len(p), c.writePackets(c.writeDeadline, []*packet{ @@ -370,6 +402,7 @@ func (c *Conn) Write(p []byte) (int, error) { Data: p, }, }, + shouldWrapCID: len(c.state.remoteConnectionID) > 0, shouldEncrypt: true, }, }) @@ -378,16 +411,25 @@ func (c *Conn) Write(p []byte) (int, error) { // Close closes the connection. func (c *Conn) Close() error { err := c.close(true) //nolint:contextcheck - c.handshakeLoopsFinished.Wait() + c.closeLock.Lock() + handshakeDone := c.handshakeDone + c.closeLock.Unlock() + if handshakeDone != nil { + <-handshakeDone + } return err } // ConnectionState returns basic DTLS details about the connection. // Note that this replaced the `Export` function of v1. -func (c *Conn) ConnectionState() State { +func (c *Conn) ConnectionState() (State, bool) { c.lock.RLock() defer c.lock.RUnlock() - return *c.state.clone() + stateClone, err := c.state.clone() + if err != nil { + return State{}, false + } + return *stateClone, true } // SelectedSRTPProtectionProfile returns the selected SRTPProtectionProfile @@ -400,6 +442,15 @@ func (c *Conn) SelectedSRTPProtectionProfile() (SRTPProtectionProfile, bool) { return profile, true } +// RemoteSRTPMasterKeyIdentifier returns the MasterKeyIdentifier value from the use_srtp +func (c *Conn) RemoteSRTPMasterKeyIdentifier() ([]byte, bool) { + if profile := c.state.getSRTPProtectionProfile(); profile == 0 { + return nil, false + } + + return c.state.remoteSRTPMasterKeyIdentifier, true +} + func (c *Conn) writePackets(ctx context.Context, pkts []*packet) error { c.lock.Lock() defer c.lock.Unlock() @@ -416,7 +467,8 @@ func (c *Conn) writePackets(ctx context.Context, pkts []*packet) error { c.log.Tracef("[handshake:%v] -> %s (epoch: %d, seq: %d)", srvCliStr(c.state.isClient), h.Header.Type.String(), p.record.Header.Epoch, h.Header.MessageSequence) - c.handshakeCache.push(handshakeRaw[recordlayer.HeaderSize:], p.record.Header.Epoch, h.Header.MessageSequence, h.Header.Type, c.state.isClient) + + c.handshakeCache.push(handshakeRaw[recordlayer.FixedHeaderSize:], p.record.Header.Epoch, h.Header.MessageSequence, h.Header.Type, c.state.isClient) rawHandshakePackets, err := c.processHandshakePacket(p, h) if err != nil { @@ -437,7 +489,7 @@ func (c *Conn) writePackets(ctx context.Context, pkts []*packet) error { compactedRawPackets := c.compactRawPackets(rawPackets) for _, compactedRawPackets := range compactedRawPackets { - if _, err := c.nextConn.WriteContext(ctx, compactedRawPackets); err != nil { + if _, err := c.nextConn.WriteToContext(ctx, compactedRawPackets, c.rAddr); err != nil { return netError(err) } } @@ -481,9 +533,44 @@ func (c *Conn) processPacket(p *packet) ([]byte, error) { } p.record.Header.SequenceNumber = seq - rawPacket, err := p.record.Marshal() - if err != nil { - return nil, err + var rawPacket []byte + if p.shouldWrapCID { + // Record must be marshaled to populate fields used in inner plaintext. + if _, err := p.record.Marshal(); err != nil { + return nil, err + } + content, err := p.record.Content.Marshal() + if err != nil { + return nil, err + } + inner := &recordlayer.InnerPlaintext{ + Content: content, + RealType: p.record.Header.ContentType, + } + rawInner, err := inner.Marshal() //nolint:govet + if err != nil { + return nil, err + } + cidHeader := &recordlayer.Header{ + Version: p.record.Header.Version, + ContentType: protocol.ContentTypeConnectionID, + Epoch: p.record.Header.Epoch, + ContentLen: uint16(len(rawInner)), + ConnectionID: c.state.remoteConnectionID, + SequenceNumber: p.record.Header.SequenceNumber, + } + rawPacket, err = cidHeader.Marshal() + if err != nil { + return nil, err + } + p.record.Header = *cidHeader + rawPacket = append(rawPacket, rawInner...) + } else { + var err error + rawPacket, err = p.record.Marshal() + if err != nil { + return nil, err + } } if p.shouldEncrypt { @@ -515,22 +602,49 @@ func (c *Conn) processHandshakePacket(p *packet, h *handshake.Handshake) ([][]by return nil, errSequenceNumberOverflow } - recordlayerHeader := &recordlayer.Header{ - Version: p.record.Header.Version, - ContentType: p.record.Header.ContentType, - ContentLen: uint16(len(handshakeFragment)), - Epoch: p.record.Header.Epoch, - SequenceNumber: seq, - } + var rawPacket []byte + if p.shouldWrapCID { + inner := &recordlayer.InnerPlaintext{ + Content: handshakeFragment, + RealType: protocol.ContentTypeHandshake, + Zeros: c.paddingLengthGenerator(uint(len(handshakeFragment))), + } + rawInner, err := inner.Marshal() //nolint:govet + if err != nil { + return nil, err + } + cidHeader := &recordlayer.Header{ + Version: p.record.Header.Version, + ContentType: protocol.ContentTypeConnectionID, + Epoch: p.record.Header.Epoch, + ContentLen: uint16(len(rawInner)), + ConnectionID: c.state.remoteConnectionID, + SequenceNumber: p.record.Header.SequenceNumber, + } + rawPacket, err = cidHeader.Marshal() + if err != nil { + return nil, err + } + p.record.Header = *cidHeader + rawPacket = append(rawPacket, rawInner...) + } else { + recordlayerHeader := &recordlayer.Header{ + Version: p.record.Header.Version, + ContentType: p.record.Header.ContentType, + ContentLen: uint16(len(handshakeFragment)), + Epoch: p.record.Header.Epoch, + SequenceNumber: seq, + } - rawPacket, err := recordlayerHeader.Marshal() - if err != nil { - return nil, err - } + rawPacket, err = recordlayerHeader.Marshal() + if err != nil { + return nil, err + } - p.record.Header = *recordlayerHeader + p.record.Header = *recordlayerHeader + rawPacket = append(rawPacket, handshakeFragment...) + } - rawPacket = append(rawPacket, handshakeFragment...) if p.shouldEncrypt { var err error rawPacket, err = c.state.cipherSuite.Encrypt(p.record, rawPacket) @@ -601,19 +715,19 @@ func (c *Conn) readAndBuffer(ctx context.Context) error { defer poolReadBuffer.Put(bufptr) b := *bufptr - i, err := c.nextConn.ReadContext(ctx, b) + i, rAddr, err := c.nextConn.ReadFromContext(ctx, b) if err != nil { return netError(err) } - pkts, err := recordlayer.UnpackDatagram(b[:i]) + pkts, err := recordlayer.ContentAwareUnpackDatagram(b[:i], len(c.state.getLocalConnectionID())) if err != nil { return err } - var hasHandshake bool + var hasHandshake, isRetransmit bool for _, p := range pkts { - hs, alert, err := c.handleIncomingPacket(ctx, p, true) + hs, rtx, alert, err := c.handleIncomingPacket(ctx, p, rAddr, true) if alert != nil { if alertErr := c.notify(ctx, alert.Level, alert.Description); alertErr != nil { if err == nil { @@ -621,21 +735,31 @@ func (c *Conn) readAndBuffer(ctx context.Context) error { } } } - if hs { - hasHandshake = true - } + var e *alertError + if errors.As(err, &e) && e.IsFatalOrCloseNotify() { + return e + } if err != nil { return err } + if hs { + hasHandshake = true + } + if rtx { + isRetransmit = true + } } if hasHandshake { - done := make(chan struct{}) + s := recvHandshakeState{ + done: make(chan struct{}), + isRetransmit: isRetransmit, + } select { - case c.handshakeRecv <- done: + case c.handshakeRecv <- s: // If the other party may retransmit the flight, // we should respond even if it not a new message. - <-done + <-s.done case <-c.fsm.Done(): } } @@ -647,7 +771,7 @@ func (c *Conn) handleQueuedPackets(ctx context.Context) error { c.encryptedPackets = nil for _, p := range pkts { - _, alert, err := c.handleIncomingPacket(ctx, p, false) // don't re-enqueue + _, _, alert, err := c.handleIncomingPacket(ctx, p.data, p.rAddr, false) // don't re-enqueue if alert != nil { if alertErr := c.notify(ctx, alert.Level, alert.Description); alertErr != nil { if err == nil { @@ -656,18 +780,17 @@ func (c *Conn) handleQueuedPackets(ctx context.Context) error { } } var e *alertError - if errors.As(err, &e) { - if e.IsFatalOrCloseNotify() { - return e - } - } else if err != nil { + if errors.As(err, &e) && e.IsFatalOrCloseNotify() { + return e + } + if err != nil { return err } } return nil } -func (c *Conn) enqueueEncryptedPackets(packet []byte) bool { +func (c *Conn) enqueueEncryptedPackets(packet addrPkt) bool { if len(c.encryptedPackets) < maxAppDataPacketQueueSize { c.encryptedPackets = append(c.encryptedPackets, packet) return true @@ -675,13 +798,18 @@ func (c *Conn) enqueueEncryptedPackets(packet []byte) bool { return false } -func (c *Conn) handleIncomingPacket(ctx context.Context, buf []byte, enqueue bool) (bool, *alert.Alert, error) { //nolint:gocognit +func (c *Conn) handleIncomingPacket(ctx context.Context, buf []byte, rAddr net.Addr, enqueue bool) (bool, bool, *alert.Alert, error) { //nolint:gocognit h := &recordlayer.Header{} + // Set connection ID size so that records of content type tls12_cid will + // be parsed correctly. + if len(c.state.getLocalConnectionID()) > 0 { + h.ConnectionID = make([]byte, len(c.state.getLocalConnectionID())) + } if err := h.Unmarshal(buf); err != nil { // Decode error must be silently discarded // [RFC6347 Section-4.1.2.7] c.log.Debugf("discarded broken packet: %v", err) - return false, nil, nil + return false, false, nil, nil } // Validate epoch remoteEpoch := c.state.getRemoteEpoch() @@ -690,14 +818,14 @@ func (c *Conn) handleIncomingPacket(ctx context.Context, buf []byte, enqueue boo c.log.Debugf("discarded future packet (epoch: %d, seq: %d)", h.Epoch, h.SequenceNumber, ) - return false, nil, nil + return false, false, nil, nil } if enqueue { - if ok := c.enqueueEncryptedPackets(buf); ok { + if ok := c.enqueueEncryptedPackets(addrPkt{rAddr, buf}); ok { c.log.Debug("received packet of next epoch, queuing packet") } } - return false, nil, nil + return false, false, nil, nil } // Anti-replay protection @@ -711,36 +839,81 @@ func (c *Conn) handleIncomingPacket(ctx context.Context, buf []byte, enqueue boo c.log.Debugf("discarded duplicated packet (epoch: %d, seq: %d)", h.Epoch, h.SequenceNumber, ) - return false, nil, nil + return false, false, nil, nil } + // originalCID indicates whether the original record had content type + // Connection ID. + originalCID := false + // Decrypt if h.Epoch != 0 { if c.state.cipherSuite == nil || !c.state.cipherSuite.IsInitialized() { if enqueue { - if ok := c.enqueueEncryptedPackets(buf); ok { + if ok := c.enqueueEncryptedPackets(addrPkt{rAddr, buf}); ok { c.log.Debug("handshake not finished, queuing packet") } } - return false, nil, nil + return false, false, nil, nil + } + + // If a connection identifier had been negotiated and encryption is + // enabled, the connection identifier MUST be sent. + if len(c.state.getLocalConnectionID()) > 0 && h.ContentType != protocol.ContentTypeConnectionID { + c.log.Debug("discarded packet missing connection ID after value negotiated") + return false, false, nil, nil } var err error - buf, err = c.state.cipherSuite.Decrypt(buf) + var hdr recordlayer.Header + if h.ContentType == protocol.ContentTypeConnectionID { + hdr.ConnectionID = make([]byte, len(c.state.getLocalConnectionID())) + } + buf, err = c.state.cipherSuite.Decrypt(hdr, buf) if err != nil { c.log.Debugf("%s: decrypt failed: %s", srvCliStr(c.state.isClient), err) - return false, nil, nil + return false, false, nil, nil + } + // If this is a connection ID record, make it look like a normal record for + // further processing. + if h.ContentType == protocol.ContentTypeConnectionID { + originalCID = true + ip := &recordlayer.InnerPlaintext{} + if err := ip.Unmarshal(buf[h.Size():]); err != nil { //nolint:govet + c.log.Debugf("unpacking inner plaintext failed: %s", err) + return false, false, nil, nil + } + unpacked := &recordlayer.Header{ + ContentType: ip.RealType, + ContentLen: uint16(len(ip.Content)), + Version: h.Version, + Epoch: h.Epoch, + SequenceNumber: h.SequenceNumber, + } + buf, err = unpacked.Marshal() + if err != nil { + c.log.Debugf("converting CID record to inner plaintext failed: %s", err) + return false, false, nil, nil + } + buf = append(buf, ip.Content...) + } + + // If connection ID does not match discard the packet. + if !bytes.Equal(c.state.getLocalConnectionID(), h.ConnectionID) { + c.log.Debug("unexpected connection ID") + return false, false, nil, nil } } - isHandshake, err := c.fragmentBuffer.push(append([]byte{}, buf...)) + isHandshake, isRetransmit, err := c.fragmentBuffer.push(append([]byte{}, buf...)) if err != nil { // Decode error must be silently discarded // [RFC6347 Section-4.1.2.7] c.log.Debugf("defragment failed: %s", err) - return false, nil, nil + return false, false, nil, nil } else if isHandshake { markPacketAsValid() + for out, epoch := c.fragmentBuffer.pop(); out != nil; out, epoch = c.fragmentBuffer.pop() { header := &handshake.Header{} if err := header.Unmarshal(out); err != nil { @@ -750,14 +923,15 @@ func (c *Conn) handleIncomingPacket(ctx context.Context, buf []byte, enqueue boo c.handshakeCache.push(out, epoch, header.MessageSequence, header.Type, !c.state.isClient) } - return true, nil, nil + return true, isRetransmit, nil, nil } r := &recordlayer.RecordLayer{} if err := r.Unmarshal(buf); err != nil { - return false, &alert.Alert{Level: alert.Fatal, Description: alert.DecodeError}, err + return false, false, &alert.Alert{Level: alert.Fatal, Description: alert.DecodeError}, err } + isLatestSeqNum := false switch content := r.Content.(type) { case *alert.Alert: c.log.Tracef("%s: <- %s", srvCliStr(c.state.isClient), content.String()) @@ -766,16 +940,16 @@ func (c *Conn) handleIncomingPacket(ctx context.Context, buf []byte, enqueue boo // Respond with a close_notify [RFC5246 Section 7.2.1] a = &alert.Alert{Level: alert.Warning, Description: alert.CloseNotify} } - markPacketAsValid() - return false, a, &alertError{content} + _ = markPacketAsValid() + return false, false, a, &alertError{content} case *protocol.ChangeCipherSpec: if c.state.cipherSuite == nil || !c.state.cipherSuite.IsInitialized() { if enqueue { - if ok := c.enqueueEncryptedPackets(buf); ok { + if ok := c.enqueueEncryptedPackets(addrPkt{rAddr, buf}); ok { c.log.Debugf("CipherSuite not initialized, queuing packet") } } - return false, nil, nil + return false, false, nil, nil } newRemoteEpoch := h.Epoch + 1 @@ -783,14 +957,14 @@ func (c *Conn) handleIncomingPacket(ctx context.Context, buf []byte, enqueue boo if c.state.getRemoteEpoch()+1 == newRemoteEpoch { c.setRemoteEpoch(newRemoteEpoch) - markPacketAsValid() + isLatestSeqNum = markPacketAsValid() } case *protocol.ApplicationData: if h.Epoch == 0 { - return false, &alert.Alert{Level: alert.Fatal, Description: alert.UnexpectedMessage}, errApplicationDataEpochZero + return false, false, &alert.Alert{Level: alert.Fatal, Description: alert.UnexpectedMessage}, errApplicationDataEpochZero } - markPacketAsValid() + isLatestSeqNum = markPacketAsValid() select { case c.decrypted <- content.Data: @@ -799,12 +973,24 @@ func (c *Conn) handleIncomingPacket(ctx context.Context, buf []byte, enqueue boo } default: - return false, &alert.Alert{Level: alert.Fatal, Description: alert.UnexpectedMessage}, fmt.Errorf("%w: %d", errUnhandledContextType, content.ContentType()) + return false, false, &alert.Alert{Level: alert.Fatal, Description: alert.UnexpectedMessage}, fmt.Errorf("%w: %d", errUnhandledContextType, content.ContentType()) + } + + // Any valid connection ID record is a candidate for updating the remote + // address if it is the latest record received. + // https://datatracker.ietf.org/doc/html/rfc9146#peer-address-update + if originalCID && isLatestSeqNum { + if rAddr != c.RemoteAddr() { + c.lock.Lock() + c.rAddr = rAddr + c.lock.Unlock() + } } - return false, nil, nil + + return false, false, nil, nil } -func (c *Conn) recvHandshake() <-chan chan struct{} { +func (c *Conn) recvHandshake() <-chan recvHandshakeState { return c.handshakeRecv } @@ -831,6 +1017,7 @@ func (c *Conn) notify(ctx context.Context, level alert.Level, desc alert.Descrip Description: desc, }, }, + shouldWrapCID: len(c.state.remoteConnectionID) > 0, shouldEncrypt: c.isHandshakeCompletedSuccessfully(), }, }) @@ -845,13 +1032,12 @@ func (c *Conn) isHandshakeCompletedSuccessfully() bool { return boolean.bool } -func (c *Conn) handshake(ctx context.Context, cfg *handshakeConfig, initialFlight flightVal, initialState handshakeState) error { //nolint:gocognit +func (c *Conn) handshake(ctx context.Context, cfg *handshakeConfig, initialFlight flightVal, initialState handshakeState) error { //nolint:gocognit,contextcheck c.fsm = newHandshakeFSM(&c.state, c.handshakeCache, cfg, initialFlight) done := make(chan struct{}) ctxRead, cancelRead := context.WithCancel(context.Background()) - c.cancelHandshakeReader = cancelRead - cfg.onFlightState = func(f flightVal, s handshakeState) { + cfg.onFlightState = func(_ flightVal, s handshakeState) { if s == handshakeFinished && !c.isHandshakeCompletedSuccessfully() { c.setHandshakeCompletedSuccessfully() close(done) @@ -859,16 +1045,21 @@ func (c *Conn) handshake(ctx context.Context, cfg *handshakeConfig, initialFligh } ctxHs, cancel := context.WithCancel(context.Background()) + + c.closeLock.Lock() c.cancelHandshaker = cancel + c.cancelHandshakeReader = cancelRead + c.closeLock.Unlock() firstErr := make(chan error, 1) - c.handshakeLoopsFinished.Add(2) + var handshakeLoopsFinished sync.WaitGroup + handshakeLoopsFinished.Add(2) // Handshake routine should be live until close. // The other party may request retransmission of the last flight to cope with packet drop. go func() { - defer c.handshakeLoopsFinished.Done() + defer handshakeLoopsFinished.Done() err := c.fsm.Run(ctxHs, c, initialState) if !errors.Is(err, context.Canceled) { select { @@ -879,14 +1070,16 @@ func (c *Conn) handshake(ctx context.Context, cfg *handshakeConfig, initialFligh }() go func() { defer func() { - // Escaping read loop. - // It's safe to close decrypted channnel now. - close(c.decrypted) + if c.isHandshakeCompletedSuccessfully() { + // Escaping read loop. + // It's safe to close decrypted channnel now. + close(c.decrypted) + } // Force stop handshaker when the underlying connection is closed. cancel() }() - defer c.handshakeLoopsFinished.Done() + defer handshakeLoopsFinished.Done() for { if err := c.readAndBuffer(ctxRead); err != nil { var e *alertError @@ -945,12 +1138,12 @@ func (c *Conn) handshake(ctx context.Context, cfg *handshakeConfig, initialFligh case err := <-firstErr: cancelRead() cancel() - c.handshakeLoopsFinished.Wait() + handshakeLoopsFinished.Wait() return c.translateHandshakeCtxError(err) case <-ctx.Done(): cancelRead() cancel() - c.handshakeLoopsFinished.Wait() + handshakeLoopsFinished.Wait() return c.translateHandshakeCtxError(ctx.Err()) case <-done: return nil @@ -968,8 +1161,13 @@ func (c *Conn) translateHandshakeCtxError(err error) error { } func (c *Conn) close(byUser bool) error { - c.cancelHandshaker() - c.cancelHandshakeReader() + c.closeLock.Lock() + cancelHandshaker := c.cancelHandshaker + cancelHandshakeReader := c.cancelHandshakeReader + c.closeLock.Unlock() + + cancelHandshaker() + cancelHandshakeReader() if c.isHandshakeCompletedSuccessfully() && byUser { // Discard error from notify() to return non-error on the first user call of Close() @@ -1022,7 +1220,9 @@ func (c *Conn) LocalAddr() net.Addr { // RemoteAddr implements net.Conn.RemoteAddr func (c *Conn) RemoteAddr() net.Addr { - return c.nextConn.RemoteAddr() + c.lock.RLock() + defer c.lock.RUnlock() + return c.rAddr } func (c *Conn) sessionKey() []byte { @@ -1030,7 +1230,7 @@ func (c *Conn) sessionKey() []byte { // As ServerName can be like 0.example.com, it's better to add // delimiter character which is not allowed to be in // neither address or domain name. - return []byte(c.nextConn.RemoteAddr().String() + "_" + c.fsm.cfg.serverName) + return []byte(c.rAddr.String() + "_" + c.fsm.cfg.serverName) } return c.state.SessionID } diff --git a/vendor/github.com/pion/dtls/v3/connection_id.go b/vendor/github.com/pion/dtls/v3/connection_id.go new file mode 100644 index 0000000000..f0e94631b7 --- /dev/null +++ b/vendor/github.com/pion/dtls/v3/connection_id.go @@ -0,0 +1,101 @@ +// SPDX-FileCopyrightText: 2023 The Pion community +// SPDX-License-Identifier: MIT + +package dtls + +import ( + "crypto/rand" + + "github.com/pion/dtls/v3/pkg/protocol" + "github.com/pion/dtls/v3/pkg/protocol/extension" + "github.com/pion/dtls/v3/pkg/protocol/handshake" + "github.com/pion/dtls/v3/pkg/protocol/recordlayer" +) + +// RandomCIDGenerator is a random Connection ID generator where CID is the +// specified size. Specifying a size of 0 will indicate to peers that sending a +// Connection ID is not necessary. +func RandomCIDGenerator(size int) func() []byte { + return func() []byte { + cid := make([]byte, size) + if _, err := rand.Read(cid); err != nil { + panic(err) //nolint -- nonrecoverable + } + return cid + } +} + +// OnlySendCIDGenerator enables sending Connection IDs negotiated with a peer, +// but indicates to the peer that sending Connection IDs in return is not +// necessary. +func OnlySendCIDGenerator() func() []byte { + return func() []byte { + return nil + } +} + +// cidDatagramRouter extracts connection IDs from incoming datagram payloads and +// uses them to route to the proper connection. +// NOTE: properly routing datagrams based on connection IDs requires using +// constant size connection IDs. +func cidDatagramRouter(size int) func([]byte) (string, bool) { + return func(packet []byte) (string, bool) { + pkts, err := recordlayer.ContentAwareUnpackDatagram(packet, size) + if err != nil || len(pkts) < 1 { + return "", false + } + for _, pkt := range pkts { + h := &recordlayer.Header{ + ConnectionID: make([]byte, size), + } + if err := h.Unmarshal(pkt); err != nil { + continue + } + if h.ContentType != protocol.ContentTypeConnectionID { + continue + } + return string(h.ConnectionID), true + } + return "", false + } +} + +// cidConnIdentifier extracts connection IDs from outgoing ServerHello records +// and associates them with the associated connection. +// NOTE: a ServerHello should always be the first record in a datagram if +// multiple are present, so we avoid iterating through all packets if the first +// is not a ServerHello. +func cidConnIdentifier() func([]byte) (string, bool) { + return func(packet []byte) (string, bool) { + pkts, err := recordlayer.UnpackDatagram(packet) + if err != nil || len(pkts) < 1 { + return "", false + } + var h recordlayer.Header + if hErr := h.Unmarshal(pkts[0]); hErr != nil { + return "", false + } + if h.ContentType != protocol.ContentTypeHandshake { + return "", false + } + var hh handshake.Header + var sh handshake.MessageServerHello + for _, pkt := range pkts { + if hhErr := hh.Unmarshal(pkt[recordlayer.FixedHeaderSize:]); hhErr != nil { + continue + } + if err = sh.Unmarshal(pkt[recordlayer.FixedHeaderSize+handshake.HeaderLength:]); err == nil { + break + } + } + if err != nil { + return "", false + } + for _, ext := range sh.Extensions { + if e, ok := ext.(*extension.ConnectionID); ok { + return string(e.CID), true + } + } + return "", false + } +} diff --git a/vendor/github.com/pion/dtls/v2/crypto.go b/vendor/github.com/pion/dtls/v3/crypto.go similarity index 96% rename from vendor/github.com/pion/dtls/v2/crypto.go rename to vendor/github.com/pion/dtls/v3/crypto.go index 968910c7ed..beddb40a8c 100644 --- a/vendor/github.com/pion/dtls/v2/crypto.go +++ b/vendor/github.com/pion/dtls/v3/crypto.go @@ -9,15 +9,14 @@ import ( "crypto/ed25519" "crypto/rand" "crypto/rsa" - "crypto/sha256" "crypto/x509" "encoding/asn1" "encoding/binary" "math/big" "time" - "github.com/pion/dtls/v2/pkg/crypto/elliptic" - "github.com/pion/dtls/v2/pkg/crypto/hash" + "github.com/pion/dtls/v3/pkg/crypto/elliptic" + "github.com/pion/dtls/v3/pkg/crypto/hash" ) type ecdsaSignature struct { @@ -118,11 +117,7 @@ func generateCertificateVerify(handshakeBodies []byte, privateKey crypto.Private return p.Sign(rand.Reader, handshakeBodies, crypto.Hash(0)) } - h := sha256.New() - if _, err := h.Write(handshakeBodies); err != nil { - return nil, err - } - hashed := h.Sum(nil) + hashed := hashAlgorithm.Digest(handshakeBodies) switch p := privateKey.(type) { case *ecdsa.PrivateKey: diff --git a/vendor/github.com/pion/dtls/v2/dtls.go b/vendor/github.com/pion/dtls/v3/dtls.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/dtls.go rename to vendor/github.com/pion/dtls/v3/dtls.go diff --git a/vendor/github.com/pion/dtls/v2/errors.go b/vendor/github.com/pion/dtls/v3/errors.go similarity index 99% rename from vendor/github.com/pion/dtls/v2/errors.go rename to vendor/github.com/pion/dtls/v3/errors.go index 025d8645ed..f03fb11c06 100644 --- a/vendor/github.com/pion/dtls/v2/errors.go +++ b/vendor/github.com/pion/dtls/v3/errors.go @@ -11,8 +11,8 @@ import ( "net" "os" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/alert" + "github.com/pion/dtls/v3/pkg/protocol" + "github.com/pion/dtls/v3/pkg/protocol/alert" ) // Typed errors diff --git a/vendor/github.com/pion/dtls/v2/errors_errno.go b/vendor/github.com/pion/dtls/v3/errors_errno.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/errors_errno.go rename to vendor/github.com/pion/dtls/v3/errors_errno.go diff --git a/vendor/github.com/pion/dtls/v2/errors_noerrno.go b/vendor/github.com/pion/dtls/v3/errors_noerrno.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/errors_noerrno.go rename to vendor/github.com/pion/dtls/v3/errors_noerrno.go diff --git a/vendor/github.com/pion/dtls/v2/flight.go b/vendor/github.com/pion/dtls/v3/flight.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/flight.go rename to vendor/github.com/pion/dtls/v3/flight.go diff --git a/vendor/github.com/pion/dtls/v2/flight0handler.go b/vendor/github.com/pion/dtls/v3/flight0handler.go similarity index 82% rename from vendor/github.com/pion/dtls/v2/flight0handler.go rename to vendor/github.com/pion/dtls/v3/flight0handler.go index a0619958ff..7bb528f1a0 100644 --- a/vendor/github.com/pion/dtls/v2/flight0handler.go +++ b/vendor/github.com/pion/dtls/v3/flight0handler.go @@ -7,11 +7,11 @@ import ( "context" "crypto/rand" - "github.com/pion/dtls/v2/pkg/crypto/elliptic" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/alert" - "github.com/pion/dtls/v2/pkg/protocol/extension" - "github.com/pion/dtls/v2/pkg/protocol/handshake" + "github.com/pion/dtls/v3/pkg/crypto/elliptic" + "github.com/pion/dtls/v3/pkg/protocol" + "github.com/pion/dtls/v3/pkg/protocol/alert" + "github.com/pion/dtls/v3/pkg/protocol/extension" + "github.com/pion/dtls/v3/pkg/protocol/handshake" ) func flight0Parse(_ context.Context, _ flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) { @@ -22,6 +22,12 @@ func flight0Parse(_ context.Context, _ flightConn, state *State, cache *handshak // No valid message received. Keep reading return 0, nil, nil } + + // Connection Identifiers must be negotiated afresh on session resumption. + // https://datatracker.ietf.org/doc/html/rfc9146#name-the-connection_id-extension + state.setLocalConnectionID(nil) + state.remoteConnectionID = nil + state.handshakeRecvSequence = seq var clientHello *handshake.MessageClientHello @@ -61,6 +67,7 @@ func flight0Parse(_ context.Context, _ flightConn, state *State, cache *handshak return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errServerNoMatchingSRTPProfile } state.setSRTPProtectionProfile(profile) + state.remoteSRTPMasterKeyIdentifier = e.MasterKeyIdentifier case *extension.UseExtendedMasterSecret: if cfg.extendedMasterSecret != DisableExtendedMasterSecret { state.extendedMasterSecret = true @@ -69,9 +76,21 @@ func flight0Parse(_ context.Context, _ flightConn, state *State, cache *handshak state.serverName = e.ServerName // remote server name case *extension.ALPN: state.peerSupportedProtocols = e.ProtocolNameList + case *extension.ConnectionID: + // Only set connection ID to be sent if server supports connection + // IDs. + if cfg.connectionIDGenerator != nil { + state.remoteConnectionID = e.CID + } } } + // If the client doesn't support connection IDs, the server should not + // expect one to be sent. + if state.remoteConnectionID == nil { + state.setLocalConnectionID(nil) + } + if cfg.extendedMasterSecret == RequireExtendedMasterSecret && !state.extendedMasterSecret { return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errServerRequiredButNoClientEMS } diff --git a/vendor/github.com/pion/dtls/v2/flight1handler.go b/vendor/github.com/pion/dtls/v3/flight1handler.go similarity index 67% rename from vendor/github.com/pion/dtls/v2/flight1handler.go rename to vendor/github.com/pion/dtls/v3/flight1handler.go index 94fdc222d0..60215c0842 100644 --- a/vendor/github.com/pion/dtls/v2/flight1handler.go +++ b/vendor/github.com/pion/dtls/v3/flight1handler.go @@ -6,12 +6,12 @@ package dtls import ( "context" - "github.com/pion/dtls/v2/pkg/crypto/elliptic" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/alert" - "github.com/pion/dtls/v2/pkg/protocol/extension" - "github.com/pion/dtls/v2/pkg/protocol/handshake" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" + "github.com/pion/dtls/v3/pkg/crypto/elliptic" + "github.com/pion/dtls/v3/pkg/protocol" + "github.com/pion/dtls/v3/pkg/protocol/alert" + "github.com/pion/dtls/v3/pkg/protocol/extension" + "github.com/pion/dtls/v3/pkg/protocol/handshake" + "github.com/pion/dtls/v3/pkg/protocol/recordlayer" ) func flight1Parse(ctx context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) { @@ -57,6 +57,10 @@ func flight1Generate(c flightConn, state *State, _ *handshakeCache, cfg *handsha return nil, nil, err } + if cfg.helloRandomBytesGenerator != nil { + state.localRandom.RandomBytes = cfg.helloRandomBytesGenerator() + } + extensions := []extension.Extension{ &extension.SupportedSignatureAlgorithms{ SignatureHashAlgorithms: cfg.localSignatureSchemes, @@ -87,7 +91,8 @@ func flight1Generate(c flightConn, state *State, _ *handshakeCache, cfg *handsha if len(cfg.localSRTPProtectionProfiles) > 0 { extensions = append(extensions, &extension.UseSRTP{ - ProtectionProfiles: cfg.localSRTPProtectionProfiles, + ProtectionProfiles: cfg.localSRTPProtectionProfiles, + MasterKeyIdentifier: cfg.localSRTPMasterKeyIdentifier, }) } @@ -118,23 +123,46 @@ func flight1Generate(c flightConn, state *State, _ *handshakeCache, cfg *handsha } } + // If we have a connection ID generator, use it. The CID may be zero length, + // in which case we are just requesting that the server send us a CID to + // use. + if cfg.connectionIDGenerator != nil { + state.setLocalConnectionID(cfg.connectionIDGenerator()) + // The presence of a generator indicates support for connection IDs. We + // use the presence of a non-nil local CID in flight 3 to determine + // whether we send a CID in the second ClientHello, so we convert any + // nil CID returned by a generator to []byte{}. + if state.getLocalConnectionID() == nil { + state.setLocalConnectionID([]byte{}) + } + extensions = append(extensions, &extension.ConnectionID{CID: state.getLocalConnectionID()}) + } + + clientHello := &handshake.MessageClientHello{ + Version: protocol.Version1_2, + SessionID: state.SessionID, + Cookie: state.cookie, + Random: state.localRandom, + CipherSuiteIDs: cipherSuiteIDs(cfg.localCipherSuites), + CompressionMethods: defaultCompressionMethods(), + Extensions: extensions, + } + + var content handshake.Handshake + + if cfg.clientHelloMessageHook != nil { + content = handshake.Handshake{Message: cfg.clientHelloMessageHook(*clientHello)} + } else { + content = handshake.Handshake{Message: clientHello} + } + return []*packet{ { record: &recordlayer.RecordLayer{ Header: recordlayer.Header{ Version: protocol.Version1_2, }, - Content: &handshake.Handshake{ - Message: &handshake.MessageClientHello{ - Version: protocol.Version1_2, - SessionID: state.SessionID, - Cookie: state.cookie, - Random: state.localRandom, - CipherSuiteIDs: cipherSuiteIDs(cfg.localCipherSuites), - CompressionMethods: defaultCompressionMethods(), - Extensions: extensions, - }, - }, + Content: &content, }, }, }, nil, nil diff --git a/vendor/github.com/pion/dtls/v2/flight2handler.go b/vendor/github.com/pion/dtls/v3/flight2handler.go similarity index 90% rename from vendor/github.com/pion/dtls/v2/flight2handler.go rename to vendor/github.com/pion/dtls/v3/flight2handler.go index 26e57d2f2d..0af457c357 100644 --- a/vendor/github.com/pion/dtls/v2/flight2handler.go +++ b/vendor/github.com/pion/dtls/v3/flight2handler.go @@ -7,10 +7,10 @@ import ( "bytes" "context" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/alert" - "github.com/pion/dtls/v2/pkg/protocol/handshake" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" + "github.com/pion/dtls/v3/pkg/protocol" + "github.com/pion/dtls/v3/pkg/protocol/alert" + "github.com/pion/dtls/v3/pkg/protocol/handshake" + "github.com/pion/dtls/v3/pkg/protocol/recordlayer" ) func flight2Parse(ctx context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) { diff --git a/vendor/github.com/pion/dtls/v2/flight3handler.go b/vendor/github.com/pion/dtls/v3/flight3handler.go similarity index 85% rename from vendor/github.com/pion/dtls/v2/flight3handler.go rename to vendor/github.com/pion/dtls/v3/flight3handler.go index ab4e730a56..f27c01a7e9 100644 --- a/vendor/github.com/pion/dtls/v2/flight3handler.go +++ b/vendor/github.com/pion/dtls/v3/flight3handler.go @@ -7,14 +7,14 @@ import ( "bytes" "context" - "github.com/pion/dtls/v2/internal/ciphersuite/types" - "github.com/pion/dtls/v2/pkg/crypto/elliptic" - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/alert" - "github.com/pion/dtls/v2/pkg/protocol/extension" - "github.com/pion/dtls/v2/pkg/protocol/handshake" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" + "github.com/pion/dtls/v3/internal/ciphersuite/types" + "github.com/pion/dtls/v3/pkg/crypto/elliptic" + "github.com/pion/dtls/v3/pkg/crypto/prf" + "github.com/pion/dtls/v3/pkg/protocol" + "github.com/pion/dtls/v3/pkg/protocol/alert" + "github.com/pion/dtls/v3/pkg/protocol/extension" + "github.com/pion/dtls/v3/pkg/protocol/handshake" + "github.com/pion/dtls/v3/pkg/protocol/recordlayer" ) func flight3Parse(ctx context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) { //nolint:gocognit @@ -57,6 +57,7 @@ func flight3Parse(ctx context.Context, c flightConn, state *State, cache *handsh return 0, &alert.Alert{Level: alert.Fatal, Description: alert.IllegalParameter}, errClientNoMatchingSRTPProfile } state.setSRTPProtectionProfile(profile) + state.remoteSRTPMasterKeyIdentifier = e.MasterKeyIdentifier case *extension.UseExtendedMasterSecret: if cfg.extendedMasterSecret != DisableExtendedMasterSecret { state.extendedMasterSecret = true @@ -66,8 +67,20 @@ func flight3Parse(ctx context.Context, c flightConn, state *State, cache *handsh return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, extension.ErrALPNInvalidFormat // Meh, internal error? } state.NegotiatedProtocol = e.ProtocolNameList[0] + case *extension.ConnectionID: + // Only set connection ID to be sent if client supports connection + // IDs. + if cfg.connectionIDGenerator != nil { + state.remoteConnectionID = e.CID + } } } + // If the server doesn't support connection IDs, the client should not + // expect one to be sent. + if state.remoteConnectionID == nil { + state.setLocalConnectionID(nil) + } + if cfg.extendedMasterSecret == RequireExtendedMasterSecret && !state.extendedMasterSecret { return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errClientRequiredButNoServerEMS } @@ -141,7 +154,8 @@ func flight3Parse(ctx context.Context, c flightConn, state *State, cache *handsh } } - if _, ok := msgs[handshake.TypeCertificateRequest].(*handshake.MessageCertificateRequest); ok { + if creq, ok := msgs[handshake.TypeCertificateRequest].(*handshake.MessageCertificateRequest); ok { + state.remoteCertRequestAlgs = creq.SignatureHashAlgorithms state.remoteRequestedCertificate = true } @@ -236,10 +250,11 @@ func flight3Generate(_ flightConn, state *State, _ *handshakeCache, cfg *handsha RenegotiatedConnection: 0, }, } + if state.namedCurve != 0 { extensions = append(extensions, []extension.Extension{ &extension.SupportedEllipticCurves{ - EllipticCurves: []elliptic.Curve{elliptic.X25519, elliptic.P256, elliptic.P384}, + EllipticCurves: cfg.ellipticCurves, }, &extension.SupportedPointFormats{ PointFormats: []elliptic.CurvePointFormat{elliptic.CurvePointFormatUncompressed}, @@ -268,23 +283,37 @@ func flight3Generate(_ flightConn, state *State, _ *handshakeCache, cfg *handsha extensions = append(extensions, &extension.ALPN{ProtocolNameList: cfg.supportedProtocols}) } + // If we sent a connection ID on the first ClientHello, send it on the + // second. + if state.getLocalConnectionID() != nil { + extensions = append(extensions, &extension.ConnectionID{CID: state.getLocalConnectionID()}) + } + + clientHello := &handshake.MessageClientHello{ + Version: protocol.Version1_2, + SessionID: state.SessionID, + Cookie: state.cookie, + Random: state.localRandom, + CipherSuiteIDs: cipherSuiteIDs(cfg.localCipherSuites), + CompressionMethods: defaultCompressionMethods(), + Extensions: extensions, + } + + var content handshake.Handshake + + if cfg.clientHelloMessageHook != nil { + content = handshake.Handshake{Message: cfg.clientHelloMessageHook(*clientHello)} + } else { + content = handshake.Handshake{Message: clientHello} + } + return []*packet{ { record: &recordlayer.RecordLayer{ Header: recordlayer.Header{ Version: protocol.Version1_2, }, - Content: &handshake.Handshake{ - Message: &handshake.MessageClientHello{ - Version: protocol.Version1_2, - SessionID: state.SessionID, - Cookie: state.cookie, - Random: state.localRandom, - CipherSuiteIDs: cipherSuiteIDs(cfg.localCipherSuites), - CompressionMethods: defaultCompressionMethods(), - Extensions: extensions, - }, - }, + Content: &content, }, }, }, nil, nil diff --git a/vendor/github.com/pion/dtls/v2/flight4bhandler.go b/vendor/github.com/pion/dtls/v3/flight4bhandler.go similarity index 79% rename from vendor/github.com/pion/dtls/v2/flight4bhandler.go rename to vendor/github.com/pion/dtls/v3/flight4bhandler.go index 6b1b904698..d87a1feeef 100644 --- a/vendor/github.com/pion/dtls/v2/flight4bhandler.go +++ b/vendor/github.com/pion/dtls/v3/flight4bhandler.go @@ -7,12 +7,12 @@ import ( "bytes" "context" - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/alert" - "github.com/pion/dtls/v2/pkg/protocol/extension" - "github.com/pion/dtls/v2/pkg/protocol/handshake" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" + "github.com/pion/dtls/v3/pkg/crypto/prf" + "github.com/pion/dtls/v3/pkg/protocol" + "github.com/pion/dtls/v3/pkg/protocol/alert" + "github.com/pion/dtls/v3/pkg/protocol/extension" + "github.com/pion/dtls/v3/pkg/protocol/handshake" + "github.com/pion/dtls/v3/pkg/protocol/recordlayer" ) func flight4bParse(_ context.Context, _ flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) { @@ -61,7 +61,8 @@ func flight4bGenerate(_ flightConn, state *State, cache *handshakeCache, cfg *ha } if state.getSRTPProtectionProfile() != 0 { extensions = append(extensions, &extension.UseSRTP{ - ProtectionProfiles: []SRTPProtectionProfile{state.getSRTPProtectionProfile()}, + ProtectionProfiles: []SRTPProtectionProfile{state.getSRTPProtectionProfile()}, + MasterKeyIdentifier: cfg.localSRTPMasterKeyIdentifier, }) } @@ -77,15 +78,21 @@ func flight4bGenerate(_ flightConn, state *State, cache *handshakeCache, cfg *ha } cipherSuiteID := uint16(state.cipherSuite.ID()) - serverHello := &handshake.Handshake{ - Message: &handshake.MessageServerHello{ - Version: protocol.Version1_2, - Random: state.localRandom, - SessionID: state.SessionID, - CipherSuiteID: &cipherSuiteID, - CompressionMethod: defaultCompressionMethods()[0], - Extensions: extensions, - }, + var serverHello handshake.Handshake + + serverHelloMessage := &handshake.MessageServerHello{ + Version: protocol.Version1_2, + Random: state.localRandom, + SessionID: state.SessionID, + CipherSuiteID: &cipherSuiteID, + CompressionMethod: defaultCompressionMethods()[0], + Extensions: extensions, + } + + if cfg.serverHelloMessageHook != nil { + serverHello = handshake.Handshake{Message: cfg.serverHelloMessageHook(*serverHelloMessage)} + } else { + serverHello = handshake.Handshake{Message: serverHelloMessage} } serverHello.Header.MessageSequence = uint16(state.handshakeSendSequence) @@ -112,7 +119,7 @@ func flight4bGenerate(_ flightConn, state *State, cache *handshakeCache, cfg *ha Header: recordlayer.Header{ Version: protocol.Version1_2, }, - Content: serverHello, + Content: &serverHello, }, }, &packet{ diff --git a/vendor/github.com/pion/dtls/v2/flight4handler.go b/vendor/github.com/pion/dtls/v3/flight4handler.go similarity index 83% rename from vendor/github.com/pion/dtls/v2/flight4handler.go rename to vendor/github.com/pion/dtls/v3/flight4handler.go index 404f7d193c..7e4ae12f15 100644 --- a/vendor/github.com/pion/dtls/v2/flight4handler.go +++ b/vendor/github.com/pion/dtls/v3/flight4handler.go @@ -8,16 +8,16 @@ import ( "crypto/rand" "crypto/x509" - "github.com/pion/dtls/v2/internal/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" - "github.com/pion/dtls/v2/pkg/crypto/elliptic" - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/crypto/signaturehash" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/alert" - "github.com/pion/dtls/v2/pkg/protocol/extension" - "github.com/pion/dtls/v2/pkg/protocol/handshake" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" + "github.com/pion/dtls/v3/internal/ciphersuite" + "github.com/pion/dtls/v3/pkg/crypto/clientcertificate" + "github.com/pion/dtls/v3/pkg/crypto/elliptic" + "github.com/pion/dtls/v3/pkg/crypto/prf" + "github.com/pion/dtls/v3/pkg/crypto/signaturehash" + "github.com/pion/dtls/v3/pkg/protocol" + "github.com/pion/dtls/v3/pkg/protocol/alert" + "github.com/pion/dtls/v3/pkg/protocol/extension" + "github.com/pion/dtls/v3/pkg/protocol/handshake" + "github.com/pion/dtls/v3/pkg/protocol/recordlayer" ) func flight4Parse(ctx context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) { //nolint:gocognit @@ -183,7 +183,11 @@ func flight4Parse(ctx context.Context, c flightConn, state *State, cache *handsh if state.cipherSuite.AuthenticationType() == CipherSuiteAuthenticationTypeAnonymous { if cfg.verifyConnection != nil { - if err := cfg.verifyConnection(state.clone()); err != nil { + stateClone, err := state.clone() + if err != nil { + return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err + } + if err := cfg.verifyConnection(stateClone); err != nil { return 0, &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, err } } @@ -210,7 +214,11 @@ func flight4Parse(ctx context.Context, c flightConn, state *State, cache *handsh // go to flight6 } if cfg.verifyConnection != nil { - if err := cfg.verifyConnection(state.clone()); err != nil { + stateClone, err := state.clone() + if err != nil { + return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err + } + if err := cfg.verifyConnection(stateClone); err != nil { return 0, &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, err } } @@ -218,7 +226,7 @@ func flight4Parse(ctx context.Context, c flightConn, state *State, cache *handsh return flight6, nil, nil } -func flight4Generate(_ flightConn, state *State, _ *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert.Alert, error) { +func flight4Generate(_ flightConn, state *State, _ *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert.Alert, error) { //nolint:gocognit extensions := []extension.Extension{&extension.RenegotiationInfo{ RenegotiatedConnection: 0, }} @@ -230,7 +238,8 @@ func flight4Generate(_ flightConn, state *State, _ *handshakeCache, cfg *handsha } if state.getSRTPProtectionProfile() != 0 { extensions = append(extensions, &extension.UseSRTP{ - ProtectionProfiles: []SRTPProtectionProfile{state.getSRTPProtectionProfile()}, + ProtectionProfiles: []SRTPProtectionProfile{state.getSRTPProtectionProfile()}, + MasterKeyIdentifier: cfg.localSRTPMasterKeyIdentifier, }) } if state.cipherSuite.AuthenticationType() == CipherSuiteAuthenticationTypeCertificate { @@ -250,6 +259,15 @@ func flight4Generate(_ flightConn, state *State, _ *handshakeCache, cfg *handsha state.NegotiatedProtocol = selectedProto } + // If we have a connection ID generator, we are willing to use connection + // IDs. We already know whether the client supports connection IDs from + // parsing the ClientHello, so avoid setting local connection ID if the + // client won't send it. + if cfg.connectionIDGenerator != nil && state.remoteConnectionID != nil { + state.setLocalConnectionID(cfg.connectionIDGenerator()) + extensions = append(extensions, &extension.ConnectionID{CID: state.getLocalConnectionID()}) + } + var pkts []*packet cipherSuiteID := uint16(state.cipherSuite.ID()) @@ -260,21 +278,29 @@ func flight4Generate(_ flightConn, state *State, _ *handshakeCache, cfg *handsha } } + serverHello := &handshake.MessageServerHello{ + Version: protocol.Version1_2, + Random: state.localRandom, + SessionID: state.SessionID, + CipherSuiteID: &cipherSuiteID, + CompressionMethod: defaultCompressionMethods()[0], + Extensions: extensions, + } + + var content handshake.Handshake + + if cfg.serverHelloMessageHook != nil { + content = handshake.Handshake{Message: cfg.serverHelloMessageHook(*serverHello)} + } else { + content = handshake.Handshake{Message: serverHello} + } + pkts = append(pkts, &packet{ record: &recordlayer.RecordLayer{ Header: recordlayer.Header{ Version: protocol.Version1_2, }, - Content: &handshake.Handshake{ - Message: &handshake.MessageServerHello{ - Version: protocol.Version1_2, - Random: state.localRandom, - SessionID: state.SessionID, - CipherSuiteID: &cipherSuiteID, - CompressionMethod: defaultCompressionMethods()[0], - Extensions: extensions, - }, - }, + Content: &content, }, }) @@ -283,6 +309,7 @@ func flight4Generate(_ flightConn, state *State, _ *handshakeCache, cfg *handsha certificate, err := cfg.getCertificate(&ClientHelloInfo{ ServerName: state.serverName, CipherSuites: []ciphersuite.ID{state.cipherSuite.ID()}, + RandomBytes: state.remoteRandom.RandomBytes, }) if err != nil { return nil, &alert.Alert{Level: alert.Fatal, Description: alert.HandshakeFailure}, err @@ -345,18 +372,27 @@ func flight4Generate(_ flightConn, state *State, _ *handshakeCache, cfg *handsha // nolint:staticcheck // ignoring tlsCert.RootCAs.Subjects is deprecated ERR because cert does not come from SystemCertPool and it's ok if certificate authorities is empty. certificateAuthorities = cfg.clientCAs.Subjects() } + + certReq := &handshake.MessageCertificateRequest{ + CertificateTypes: []clientcertificate.Type{clientcertificate.RSASign, clientcertificate.ECDSASign}, + SignatureHashAlgorithms: cfg.localSignatureSchemes, + CertificateAuthoritiesNames: certificateAuthorities, + } + + var content handshake.Handshake + + if cfg.certificateRequestMessageHook != nil { + content = handshake.Handshake{Message: cfg.certificateRequestMessageHook(*certReq)} + } else { + content = handshake.Handshake{Message: certReq} + } + pkts = append(pkts, &packet{ record: &recordlayer.RecordLayer{ Header: recordlayer.Header{ Version: protocol.Version1_2, }, - Content: &handshake.Handshake{ - Message: &handshake.MessageCertificateRequest{ - CertificateTypes: []clientcertificate.Type{clientcertificate.RSASign, clientcertificate.ECDSASign}, - SignatureHashAlgorithms: cfg.localSignatureSchemes, - CertificateAuthoritiesNames: certificateAuthorities, - }, - }, + Content: &content, }, }) } diff --git a/vendor/github.com/pion/dtls/v2/flight5bhandler.go b/vendor/github.com/pion/dtls/v3/flight5bhandler.go similarity index 90% rename from vendor/github.com/pion/dtls/v2/flight5bhandler.go rename to vendor/github.com/pion/dtls/v3/flight5bhandler.go index ddd37324c6..27a05cc21f 100644 --- a/vendor/github.com/pion/dtls/v2/flight5bhandler.go +++ b/vendor/github.com/pion/dtls/v3/flight5bhandler.go @@ -6,11 +6,11 @@ package dtls import ( "context" - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/alert" - "github.com/pion/dtls/v2/pkg/protocol/handshake" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" + "github.com/pion/dtls/v3/pkg/crypto/prf" + "github.com/pion/dtls/v3/pkg/protocol" + "github.com/pion/dtls/v3/pkg/protocol/alert" + "github.com/pion/dtls/v3/pkg/protocol/handshake" + "github.com/pion/dtls/v3/pkg/protocol/recordlayer" ) func flight5bParse(_ context.Context, _ flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) { diff --git a/vendor/github.com/pion/dtls/v2/flight5handler.go b/vendor/github.com/pion/dtls/v3/flight5handler.go similarity index 93% rename from vendor/github.com/pion/dtls/v2/flight5handler.go rename to vendor/github.com/pion/dtls/v3/flight5handler.go index e8adf4f362..7e940cdc92 100644 --- a/vendor/github.com/pion/dtls/v2/flight5handler.go +++ b/vendor/github.com/pion/dtls/v3/flight5handler.go @@ -9,12 +9,12 @@ import ( "crypto" "crypto/x509" - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/crypto/signaturehash" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/alert" - "github.com/pion/dtls/v2/pkg/protocol/handshake" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" + "github.com/pion/dtls/v3/pkg/crypto/prf" + "github.com/pion/dtls/v3/pkg/crypto/signaturehash" + "github.com/pion/dtls/v3/pkg/protocol" + "github.com/pion/dtls/v3/pkg/protocol/alert" + "github.com/pion/dtls/v3/pkg/protocol/handshake" + "github.com/pion/dtls/v3/pkg/protocol/recordlayer" ) func flight5Parse(_ context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) { @@ -173,7 +173,7 @@ func flight5Generate(c flightConn, state *State, cache *handshakeCache, cfg *han merged = append(merged, raw...) } - if alertPtr, err := initalizeCipherSuite(state, cache, cfg, serverKeyExchange, merged); err != nil { + if alertPtr, err := initializeCipherSuite(state, cache, cfg, serverKeyExchange, merged); err != nil { return nil, alertPtr, err } @@ -193,7 +193,8 @@ func flight5Generate(c flightConn, state *State, cache *handshakeCache, cfg *han ), merged...) // Find compatible signature scheme - signatureHashAlgo, err := signaturehash.SelectSignatureScheme(cfg.localSignatureSchemes, privateKey) + + signatureHashAlgo, err := signaturehash.SelectSignatureScheme(state.remoteCertRequestAlgs, privateKey) if err != nil { return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, err } @@ -277,6 +278,7 @@ func flight5Generate(c flightConn, state *State, cache *handshakeCache, cfg *han }, }, }, + shouldWrapCID: len(state.remoteConnectionID) > 0, shouldEncrypt: true, resetLocalSequenceNumber: true, }) @@ -284,7 +286,7 @@ func flight5Generate(c flightConn, state *State, cache *handshakeCache, cfg *han return pkts, nil, nil } -func initalizeCipherSuite(state *State, cache *handshakeCache, cfg *handshakeConfig, h *handshake.MessageServerKeyExchange, sendingPlainText []byte) (*alert.Alert, error) { //nolint:gocognit +func initializeCipherSuite(state *State, cache *handshakeCache, cfg *handshakeConfig, h *handshake.MessageServerKeyExchange, sendingPlainText []byte) (*alert.Alert, error) { //nolint:gocognit if state.cipherSuite.IsInitialized() { return nil, nil //nolint } @@ -342,8 +344,12 @@ func initalizeCipherSuite(state *State, cache *handshakeCache, cfg *handshakeCon } } if cfg.verifyConnection != nil { - if err = cfg.verifyConnection(state.clone()); err != nil { - return &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, err + stateClone, errC := state.clone() + if errC != nil { + return &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, errC + } + if errC = cfg.verifyConnection(stateClone); errC != nil { + return &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, errC } } diff --git a/vendor/github.com/pion/dtls/v2/flight6handler.go b/vendor/github.com/pion/dtls/v3/flight6handler.go similarity index 90% rename from vendor/github.com/pion/dtls/v2/flight6handler.go rename to vendor/github.com/pion/dtls/v3/flight6handler.go index 57ac143600..576dc551b1 100644 --- a/vendor/github.com/pion/dtls/v2/flight6handler.go +++ b/vendor/github.com/pion/dtls/v3/flight6handler.go @@ -6,11 +6,11 @@ package dtls import ( "context" - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/alert" - "github.com/pion/dtls/v2/pkg/protocol/handshake" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" + "github.com/pion/dtls/v3/pkg/crypto/prf" + "github.com/pion/dtls/v3/pkg/protocol" + "github.com/pion/dtls/v3/pkg/protocol/alert" + "github.com/pion/dtls/v3/pkg/protocol/handshake" + "github.com/pion/dtls/v3/pkg/protocol/recordlayer" ) func flight6Parse(_ context.Context, _ flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) { @@ -77,6 +77,7 @@ func flight6Generate(_ flightConn, state *State, cache *handshakeCache, cfg *han }, }, }, + shouldWrapCID: len(state.remoteConnectionID) > 0, shouldEncrypt: true, resetLocalSequenceNumber: true, }, diff --git a/vendor/github.com/pion/dtls/v2/flighthandler.go b/vendor/github.com/pion/dtls/v3/flighthandler.go similarity index 97% rename from vendor/github.com/pion/dtls/v2/flighthandler.go rename to vendor/github.com/pion/dtls/v3/flighthandler.go index ceb4a992b7..651ff17e07 100644 --- a/vendor/github.com/pion/dtls/v2/flighthandler.go +++ b/vendor/github.com/pion/dtls/v3/flighthandler.go @@ -6,7 +6,7 @@ package dtls import ( "context" - "github.com/pion/dtls/v2/pkg/protocol/alert" + "github.com/pion/dtls/v3/pkg/protocol/alert" ) // Parse received handshakes and return next flightVal diff --git a/vendor/github.com/pion/dtls/v2/fragment_buffer.go b/vendor/github.com/pion/dtls/v3/fragment_buffer.go similarity index 82% rename from vendor/github.com/pion/dtls/v2/fragment_buffer.go rename to vendor/github.com/pion/dtls/v3/fragment_buffer.go index f200337589..37223ab07d 100644 --- a/vendor/github.com/pion/dtls/v2/fragment_buffer.go +++ b/vendor/github.com/pion/dtls/v3/fragment_buffer.go @@ -4,9 +4,9 @@ package dtls import ( - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/handshake" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" + "github.com/pion/dtls/v3/pkg/protocol" + "github.com/pion/dtls/v3/pkg/protocol/handshake" + "github.com/pion/dtls/v3/pkg/protocol/recordlayer" ) // 2 megabytes @@ -43,26 +43,29 @@ func (f *fragmentBuffer) size() int { // Attempts to push a DTLS packet to the fragmentBuffer // when it returns true it means the fragmentBuffer has inserted and the buffer shouldn't be handled // when an error returns it is fatal, and the DTLS connection should be stopped -func (f *fragmentBuffer) push(buf []byte) (bool, error) { +func (f *fragmentBuffer) push(buf []byte) (isHandshake, isRetransmit bool, err error) { if f.size()+len(buf) >= fragmentBufferMaxSize { - return false, errFragmentBufferOverflow + return false, false, errFragmentBufferOverflow } frag := new(fragment) if err := frag.recordLayerHeader.Unmarshal(buf); err != nil { - return false, err + return false, false, err } // fragment isn't a handshake, we don't need to handle it if frag.recordLayerHeader.ContentType != protocol.ContentTypeHandshake { - return false, nil + return false, false, nil } - for buf = buf[recordlayer.HeaderSize:]; len(buf) != 0; frag = new(fragment) { + for buf = buf[recordlayer.FixedHeaderSize:]; len(buf) != 0; frag = new(fragment) { if err := frag.handshakeHeader.Unmarshal(buf); err != nil { - return false, err + return false, false, err } + // Fragment is a retransmission. We have already assembled it before successfully + isRetransmit = frag.handshakeHeader.FragmentOffset == 0 && frag.handshakeHeader.MessageSequence < f.currentMessageSequenceNumber + if _, ok := f.cache[frag.handshakeHeader.MessageSequence]; !ok { f.cache[frag.handshakeHeader.MessageSequence] = []*fragment{} } @@ -80,7 +83,7 @@ func (f *fragmentBuffer) push(buf []byte) (bool, error) { buf = buf[end:] } - return true, nil + return true, isRetransmit, nil } func (f *fragmentBuffer) pop() (content []byte, epoch uint16) { diff --git a/vendor/github.com/pion/dtls/v2/handshake_cache.go b/vendor/github.com/pion/dtls/v3/handshake_cache.go similarity index 96% rename from vendor/github.com/pion/dtls/v2/handshake_cache.go rename to vendor/github.com/pion/dtls/v3/handshake_cache.go index 8d5960568a..285c713319 100644 --- a/vendor/github.com/pion/dtls/v2/handshake_cache.go +++ b/vendor/github.com/pion/dtls/v3/handshake_cache.go @@ -6,8 +6,8 @@ package dtls import ( "sync" - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/protocol/handshake" + "github.com/pion/dtls/v3/pkg/crypto/prf" + "github.com/pion/dtls/v3/pkg/protocol/handshake" ) type handshakeCacheItem struct { @@ -97,6 +97,7 @@ func (h *handshakeCache) fullPullMap(startSeq int, cipherSuite CipherSuite, rule } out := make(map[handshake.Type]handshake.Message) seq := startSeq + ok := false for _, r := range rules { t := r.typ i := ci[t] @@ -118,8 +119,12 @@ func (h *handshakeCache) fullPullMap(startSeq int, cipherSuite CipherSuite, rule return startSeq, nil, false } seq++ + ok = true out[t] = rawHandshake.Message } + if !ok { + return seq, nil, false + } return seq, out, true } diff --git a/vendor/github.com/pion/dtls/v2/handshaker.go b/vendor/github.com/pion/dtls/v3/handshaker.go similarity index 69% rename from vendor/github.com/pion/dtls/v2/handshaker.go rename to vendor/github.com/pion/dtls/v3/handshaker.go index 1c6d58fe99..5e16808a90 100644 --- a/vendor/github.com/pion/dtls/v2/handshaker.go +++ b/vendor/github.com/pion/dtls/v3/handshaker.go @@ -12,10 +12,10 @@ import ( "sync" "time" - "github.com/pion/dtls/v2/pkg/crypto/elliptic" - "github.com/pion/dtls/v2/pkg/crypto/signaturehash" - "github.com/pion/dtls/v2/pkg/protocol/alert" - "github.com/pion/dtls/v2/pkg/protocol/handshake" + "github.com/pion/dtls/v3/pkg/crypto/elliptic" + "github.com/pion/dtls/v3/pkg/crypto/signaturehash" + "github.com/pion/dtls/v3/pkg/protocol/alert" + "github.com/pion/dtls/v3/pkg/protocol/handshake" "github.com/pion/logging" ) @@ -82,37 +82,42 @@ func (s handshakeState) String() string { } type handshakeFSM struct { - currentFlight flightVal - flights []*packet - retransmit bool - state *State - cache *handshakeCache - cfg *handshakeConfig - closed chan struct{} + currentFlight flightVal + flights []*packet + retransmit bool + retransmitInterval time.Duration + state *State + cache *handshakeCache + cfg *handshakeConfig + closed chan struct{} } type handshakeConfig struct { - localPSKCallback PSKCallback - localPSKIdentityHint []byte - localCipherSuites []CipherSuite // Available CipherSuites - localSignatureSchemes []signaturehash.Algorithm // Available signature schemes - extendedMasterSecret ExtendedMasterSecretType // Policy for the Extended Master Support extension - localSRTPProtectionProfiles []SRTPProtectionProfile // Available SRTPProtectionProfiles, if empty no SRTP support - serverName string - supportedProtocols []string - clientAuth ClientAuthType // If we are a client should we request a client certificate - localCertificates []tls.Certificate - nameToCertificate map[string]*tls.Certificate - insecureSkipVerify bool - verifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error - verifyConnection func(*State) error - sessionStore SessionStore - rootCAs *x509.CertPool - clientCAs *x509.CertPool - retransmitInterval time.Duration - customCipherSuites func() []CipherSuite - ellipticCurves []elliptic.Curve - insecureSkipHelloVerify bool + localPSKCallback PSKCallback + localPSKIdentityHint []byte + localCipherSuites []CipherSuite // Available CipherSuites + localSignatureSchemes []signaturehash.Algorithm // Available signature schemes + extendedMasterSecret ExtendedMasterSecretType // Policy for the Extended Master Support extension + localSRTPProtectionProfiles []SRTPProtectionProfile // Available SRTPProtectionProfiles, if empty no SRTP support + localSRTPMasterKeyIdentifier []byte + serverName string + supportedProtocols []string + clientAuth ClientAuthType // If we are a client should we request a client certificate + localCertificates []tls.Certificate + nameToCertificate map[string]*tls.Certificate + insecureSkipVerify bool + verifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error + verifyConnection func(*State) error + sessionStore SessionStore + rootCAs *x509.CertPool + clientCAs *x509.CertPool + initialRetransmitInterval time.Duration + disableRetransmitBackoff bool + customCipherSuites func() []CipherSuite + ellipticCurves []elliptic.Curve + insecureSkipHelloVerify bool + connectionIDGenerator func() []byte + helloRandomBytesGenerator func() [handshake.RandomBytesLength]byte onFlightState func(flightVal, handshakeState) log logging.LeveledLogger @@ -124,12 +129,18 @@ type handshakeConfig struct { initialEpoch uint16 mu sync.Mutex + + clientHelloMessageHook func(handshake.MessageClientHello) handshake.Message + serverHelloMessageHook func(handshake.MessageServerHello) handshake.Message + certificateRequestMessageHook func(handshake.MessageCertificateRequest) handshake.Message + + resumeState *State } type flightConn interface { notify(ctx context.Context, level alert.Level, desc alert.Description) error writePackets(context.Context, []*packet) error - recvHandshake() <-chan chan struct{} + recvHandshake() <-chan recvHandshakeState setLocalEpoch(epoch uint16) handleQueuedPackets(context.Context) error sessionKey() []byte @@ -159,11 +170,12 @@ func newHandshakeFSM( initialFlight flightVal, ) *handshakeFSM { return &handshakeFSM{ - currentFlight: initialFlight, - state: s, - cache: cache, - cfg: cfg, - closed: make(chan struct{}), + currentFlight: initialFlight, + state: s, + cache: cache, + cfg: cfg, + retransmitInterval: cfg.initialRetransmitInterval, + closed: make(chan struct{}), } } @@ -263,19 +275,23 @@ func (s *handshakeFSM) wait(ctx context.Context, c flightConn) (handshakeState, parse, errFlight := s.currentFlight.getFlightParser() if errFlight != nil { if alertErr := c.notify(ctx, alert.Fatal, alert.InternalError); alertErr != nil { - if errFlight != nil { - return handshakeErrored, alertErr - } + return handshakeErrored, alertErr } return handshakeErrored, errFlight } - retransmitTimer := time.NewTimer(s.cfg.retransmitInterval) + retransmitTimer := time.NewTimer(s.retransmitInterval) for { select { - case done := <-c.recvHandshake(): + case state := <-c.recvHandshake(): + if state.isRetransmit { + close(state.done) + return handshakeSending, nil + } + nextFlight, alert, err := parse(ctx, c, s.state, s.cache, s.cfg) - close(done) + s.retransmitInterval = s.cfg.initialRetransmitInterval + close(state.done) if alert != nil { if alertErr := c.notify(ctx, alert.Level, alert.Description); alertErr != nil { if err != nil { @@ -300,51 +316,34 @@ func (s *handshakeFSM) wait(ctx context.Context, c flightConn) (handshakeState, if !s.retransmit { return handshakeWaiting, nil } + + // RFC 4347 4.2.4.1: + // Implementations SHOULD use an initial timer value of 1 second (the minimum defined in RFC 2988 [RFC2988]) + // and double the value at each retransmission, up to no less than the RFC 2988 maximum of 60 seconds. + if !s.cfg.disableRetransmitBackoff { + s.retransmitInterval *= 2 + } + if s.retransmitInterval > time.Second*60 { + s.retransmitInterval = time.Second * 60 + } return handshakeSending, nil case <-ctx.Done(): + s.retransmitInterval = s.cfg.initialRetransmitInterval return handshakeErrored, ctx.Err() } } } func (s *handshakeFSM) finish(ctx context.Context, c flightConn) (handshakeState, error) { - parse, errFlight := s.currentFlight.getFlightParser() - if errFlight != nil { - if alertErr := c.notify(ctx, alert.Fatal, alert.InternalError); alertErr != nil { - if errFlight != nil { - return handshakeErrored, alertErr - } - } - return handshakeErrored, errFlight - } - - retransmitTimer := time.NewTimer(s.cfg.retransmitInterval) select { - case done := <-c.recvHandshake(): - nextFlight, alert, err := parse(ctx, c, s.state, s.cache, s.cfg) - close(done) - if alert != nil { - if alertErr := c.notify(ctx, alert.Level, alert.Description); alertErr != nil { - if err != nil { - err = alertErr - } - } - } - if err != nil { - return handshakeErrored, err - } - if nextFlight == 0 { - break - } - if nextFlight.isLastRecvFlight() && s.currentFlight == nextFlight { + case state := <-c.recvHandshake(): + close(state.done) + if s.state.isClient { return handshakeFinished, nil + } else { + return handshakeSending, nil } - <-retransmitTimer.C - // Retransmit last flight - return handshakeSending, nil - case <-ctx.Done(): return handshakeErrored, ctx.Err() } - return handshakeFinished, nil } diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_128_ccm.go b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/aes_128_ccm.go similarity index 90% rename from vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_128_ccm.go rename to vendor/github.com/pion/dtls/v3/internal/ciphersuite/aes_128_ccm.go index f78b6dc2c5..0877c2c180 100644 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_128_ccm.go +++ b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/aes_128_ccm.go @@ -4,8 +4,8 @@ package ciphersuite import ( - "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" + "github.com/pion/dtls/v3/pkg/crypto/ciphersuite" + "github.com/pion/dtls/v3/pkg/crypto/clientcertificate" ) // Aes128Ccm is a base class used by multiple AES-CCM Ciphers diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_256_ccm.go b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/aes_256_ccm.go similarity index 90% rename from vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_256_ccm.go rename to vendor/github.com/pion/dtls/v3/internal/ciphersuite/aes_256_ccm.go index bb8128627d..bbdf06d811 100644 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_256_ccm.go +++ b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/aes_256_ccm.go @@ -4,8 +4,8 @@ package ciphersuite import ( - "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" + "github.com/pion/dtls/v3/pkg/crypto/ciphersuite" + "github.com/pion/dtls/v3/pkg/crypto/clientcertificate" ) // Aes256Ccm is a base class used by multiple AES-CCM Ciphers diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_ccm.go b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/aes_ccm.go similarity index 90% rename from vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_ccm.go rename to vendor/github.com/pion/dtls/v3/internal/ciphersuite/aes_ccm.go index dc51198237..54eafcf80d 100644 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_ccm.go +++ b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/aes_ccm.go @@ -9,10 +9,10 @@ import ( "hash" "sync/atomic" - "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" + "github.com/pion/dtls/v3/pkg/crypto/ciphersuite" + "github.com/pion/dtls/v3/pkg/crypto/clientcertificate" + "github.com/pion/dtls/v3/pkg/crypto/prf" + "github.com/pion/dtls/v3/pkg/protocol/recordlayer" ) // AesCcm is a base class used by multiple AES-CCM Ciphers @@ -103,11 +103,11 @@ func (c *AesCcm) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, erro } // Decrypt decrypts a single TLS RecordLayer -func (c *AesCcm) Decrypt(raw []byte) ([]byte, error) { +func (c *AesCcm) Decrypt(h recordlayer.Header, raw []byte) ([]byte, error) { cipherSuite, ok := c.ccm.Load().(*ciphersuite.CCM) if !ok { return nil, fmt.Errorf("%w, unable to decrypt", errCipherSuiteNotInit) } - return cipherSuite.Decrypt(raw) + return cipherSuite.Decrypt(h, raw) } diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/ciphersuite.go b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/ciphersuite.go similarity index 97% rename from vendor/github.com/pion/dtls/v2/internal/ciphersuite/ciphersuite.go rename to vendor/github.com/pion/dtls/v3/internal/ciphersuite/ciphersuite.go index f44f29fd39..4778be72ad 100644 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/ciphersuite.go +++ b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/ciphersuite.go @@ -8,8 +8,8 @@ import ( "errors" "fmt" - "github.com/pion/dtls/v2/internal/ciphersuite/types" - "github.com/pion/dtls/v2/pkg/protocol" + "github.com/pion/dtls/v3/internal/ciphersuite/types" + "github.com/pion/dtls/v3/pkg/protocol" ) var errCipherSuiteNotInit = &protocol.TemporaryError{Err: errors.New("CipherSuite has not been initialized")} //nolint:goerr113 diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_ccm.go b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_ccm.go similarity index 79% rename from vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_ccm.go rename to vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_ccm.go index 8367b2c6d6..e552907995 100644 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_ccm.go +++ b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_ccm.go @@ -4,8 +4,8 @@ package ciphersuite import ( - "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" + "github.com/pion/dtls/v3/pkg/crypto/ciphersuite" + "github.com/pion/dtls/v3/pkg/crypto/clientcertificate" ) // NewTLSEcdheEcdsaWithAes128Ccm constructs a TLS_ECDHE_ECDSA_WITH_AES_128_CCM Cipher diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_ccm8.go b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_ccm8.go similarity index 80% rename from vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_ccm8.go rename to vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_ccm8.go index 11b6873274..a423a13f12 100644 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_ccm8.go +++ b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_ccm8.go @@ -4,8 +4,8 @@ package ciphersuite import ( - "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" + "github.com/pion/dtls/v3/pkg/crypto/ciphersuite" + "github.com/pion/dtls/v3/pkg/crypto/clientcertificate" ) // NewTLSEcdheEcdsaWithAes128Ccm8 creates a new TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 CipherSuite diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_gcm_sha256.go b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_gcm_sha256.go similarity index 90% rename from vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_gcm_sha256.go rename to vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_gcm_sha256.go index 0c919fe47a..9f7b277887 100644 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_gcm_sha256.go +++ b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_gcm_sha256.go @@ -9,10 +9,10 @@ import ( "hash" "sync/atomic" - "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" + "github.com/pion/dtls/v3/pkg/crypto/ciphersuite" + "github.com/pion/dtls/v3/pkg/crypto/clientcertificate" + "github.com/pion/dtls/v3/pkg/crypto/prf" + "github.com/pion/dtls/v3/pkg/protocol/recordlayer" ) // TLSEcdheEcdsaWithAes128GcmSha256 represents a TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 CipherSuite @@ -98,11 +98,11 @@ func (c *TLSEcdheEcdsaWithAes128GcmSha256) Encrypt(pkt *recordlayer.RecordLayer, } // Decrypt decrypts a single TLS RecordLayer -func (c *TLSEcdheEcdsaWithAes128GcmSha256) Decrypt(raw []byte) ([]byte, error) { +func (c *TLSEcdheEcdsaWithAes128GcmSha256) Decrypt(h recordlayer.Header, raw []byte) ([]byte, error) { cipherSuite, ok := c.gcm.Load().(*ciphersuite.GCM) if !ok { return nil, fmt.Errorf("%w, unable to decrypt", errCipherSuiteNotInit) } - return cipherSuite.Decrypt(raw) + return cipherSuite.Decrypt(h, raw) } diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_256_cbc_sha.go b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_256_cbc_sha.go similarity index 90% rename from vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_256_cbc_sha.go rename to vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_256_cbc_sha.go index 577192c89b..87f5ef395d 100644 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_256_cbc_sha.go +++ b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_256_cbc_sha.go @@ -10,10 +10,10 @@ import ( "hash" "sync/atomic" - "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" + "github.com/pion/dtls/v3/pkg/crypto/ciphersuite" + "github.com/pion/dtls/v3/pkg/crypto/clientcertificate" + "github.com/pion/dtls/v3/pkg/crypto/prf" + "github.com/pion/dtls/v3/pkg/protocol/recordlayer" ) // TLSEcdheEcdsaWithAes256CbcSha represents a TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA CipherSuite @@ -104,11 +104,11 @@ func (c *TLSEcdheEcdsaWithAes256CbcSha) Encrypt(pkt *recordlayer.RecordLayer, ra } // Decrypt decrypts a single TLS RecordLayer -func (c *TLSEcdheEcdsaWithAes256CbcSha) Decrypt(raw []byte) ([]byte, error) { +func (c *TLSEcdheEcdsaWithAes256CbcSha) Decrypt(h recordlayer.Header, raw []byte) ([]byte, error) { cipherSuite, ok := c.cbc.Load().(*ciphersuite.CBC) if !ok { return nil, fmt.Errorf("%w, unable to decrypt", errCipherSuiteNotInit) } - return cipherSuite.Decrypt(raw) + return cipherSuite.Decrypt(h, raw) } diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_256_gcm_sha384.go b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_256_gcm_sha384.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_256_gcm_sha384.go rename to vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_256_gcm_sha384.go diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_psk_with_aes_128_cbc_sha256.go b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_psk_with_aes_128_cbc_sha256.go similarity index 90% rename from vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_psk_with_aes_128_cbc_sha256.go rename to vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_psk_with_aes_128_cbc_sha256.go index 75a25633a4..87b80f4213 100644 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_psk_with_aes_128_cbc_sha256.go +++ b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_psk_with_aes_128_cbc_sha256.go @@ -9,10 +9,10 @@ import ( "hash" "sync/atomic" - "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" + "github.com/pion/dtls/v3/pkg/crypto/ciphersuite" + "github.com/pion/dtls/v3/pkg/crypto/clientcertificate" + "github.com/pion/dtls/v3/pkg/crypto/prf" + "github.com/pion/dtls/v3/pkg/protocol/recordlayer" ) // TLSEcdhePskWithAes128CbcSha256 implements the TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 CipherSuite @@ -108,11 +108,11 @@ func (c *TLSEcdhePskWithAes128CbcSha256) Encrypt(pkt *recordlayer.RecordLayer, r } // Decrypt decrypts a single TLS RecordLayer -func (c *TLSEcdhePskWithAes128CbcSha256) Decrypt(raw []byte) ([]byte, error) { +func (c *TLSEcdhePskWithAes128CbcSha256) Decrypt(h recordlayer.Header, raw []byte) ([]byte, error) { cipherSuite, ok := c.cbc.Load().(*ciphersuite.CBC) if !ok { // !c.isInitialized() return nil, fmt.Errorf("%w, unable to decrypt", errCipherSuiteNotInit) } - return cipherSuite.Decrypt(raw) + return cipherSuite.Decrypt(h, raw) } diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_128_gcm_sha256.go b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_rsa_with_aes_128_gcm_sha256.go similarity index 92% rename from vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_128_gcm_sha256.go rename to vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_rsa_with_aes_128_gcm_sha256.go index 478a2e0dc9..5ac17ed97d 100644 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_128_gcm_sha256.go +++ b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_rsa_with_aes_128_gcm_sha256.go @@ -3,7 +3,7 @@ package ciphersuite -import "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" +import "github.com/pion/dtls/v3/pkg/crypto/clientcertificate" // TLSEcdheRsaWithAes128GcmSha256 implements the TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 CipherSuite type TLSEcdheRsaWithAes128GcmSha256 struct { diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_256_cbc_sha.go b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_rsa_with_aes_256_cbc_sha.go similarity index 92% rename from vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_256_cbc_sha.go rename to vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_rsa_with_aes_256_cbc_sha.go index 8e88ee6392..545c2e46f6 100644 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_256_cbc_sha.go +++ b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_rsa_with_aes_256_cbc_sha.go @@ -3,7 +3,7 @@ package ciphersuite -import "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" +import "github.com/pion/dtls/v3/pkg/crypto/clientcertificate" // TLSEcdheRsaWithAes256CbcSha implements the TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA CipherSuite type TLSEcdheRsaWithAes256CbcSha struct { diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_256_gcm_sha384.go b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_rsa_with_aes_256_gcm_sha384.go similarity index 92% rename from vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_256_gcm_sha384.go rename to vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_rsa_with_aes_256_gcm_sha384.go index 752fb529cf..5750cc3863 100644 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_256_gcm_sha384.go +++ b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_ecdhe_rsa_with_aes_256_gcm_sha384.go @@ -3,7 +3,7 @@ package ciphersuite -import "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" +import "github.com/pion/dtls/v3/pkg/crypto/clientcertificate" // TLSEcdheRsaWithAes256GcmSha384 implements the TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 CipherSuite type TLSEcdheRsaWithAes256GcmSha384 struct { diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_cbc_sha256.go b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_psk_with_aes_128_cbc_sha256.go similarity index 90% rename from vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_cbc_sha256.go rename to vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_psk_with_aes_128_cbc_sha256.go index 7336ad946a..dc485c46bd 100644 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_cbc_sha256.go +++ b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_psk_with_aes_128_cbc_sha256.go @@ -9,10 +9,10 @@ import ( "hash" "sync/atomic" - "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" + "github.com/pion/dtls/v3/pkg/crypto/ciphersuite" + "github.com/pion/dtls/v3/pkg/crypto/clientcertificate" + "github.com/pion/dtls/v3/pkg/crypto/prf" + "github.com/pion/dtls/v3/pkg/protocol/recordlayer" ) // TLSPskWithAes128CbcSha256 implements the TLS_PSK_WITH_AES_128_CBC_SHA256 CipherSuite @@ -103,11 +103,11 @@ func (c *TLSPskWithAes128CbcSha256) Encrypt(pkt *recordlayer.RecordLayer, raw [] } // Decrypt decrypts a single TLS RecordLayer -func (c *TLSPskWithAes128CbcSha256) Decrypt(raw []byte) ([]byte, error) { +func (c *TLSPskWithAes128CbcSha256) Decrypt(h recordlayer.Header, raw []byte) ([]byte, error) { cipherSuite, ok := c.cbc.Load().(*ciphersuite.CBC) if !ok { return nil, fmt.Errorf("%w, unable to decrypt", errCipherSuiteNotInit) } - return cipherSuite.Decrypt(raw) + return cipherSuite.Decrypt(h, raw) } diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_ccm.go b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_psk_with_aes_128_ccm.go similarity index 78% rename from vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_ccm.go rename to vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_psk_with_aes_128_ccm.go index 1ded09b881..6344f11fb7 100644 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_ccm.go +++ b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_psk_with_aes_128_ccm.go @@ -4,8 +4,8 @@ package ciphersuite import ( - "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" + "github.com/pion/dtls/v3/pkg/crypto/ciphersuite" + "github.com/pion/dtls/v3/pkg/crypto/clientcertificate" ) // NewTLSPskWithAes128Ccm returns the TLS_PSK_WITH_AES_128_CCM CipherSuite diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_ccm8.go b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_psk_with_aes_128_ccm8.go similarity index 79% rename from vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_ccm8.go rename to vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_psk_with_aes_128_ccm8.go index 4781970741..4b08275337 100644 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_ccm8.go +++ b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_psk_with_aes_128_ccm8.go @@ -4,8 +4,8 @@ package ciphersuite import ( - "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" + "github.com/pion/dtls/v3/pkg/crypto/ciphersuite" + "github.com/pion/dtls/v3/pkg/crypto/clientcertificate" ) // NewTLSPskWithAes128Ccm8 returns the TLS_PSK_WITH_AES_128_CCM_8 CipherSuite diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_gcm_sha256.go b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_psk_with_aes_128_gcm_sha256.go similarity index 94% rename from vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_gcm_sha256.go rename to vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_psk_with_aes_128_gcm_sha256.go index 8ab5b89a8d..3a5e7e753c 100644 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_gcm_sha256.go +++ b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_psk_with_aes_128_gcm_sha256.go @@ -3,7 +3,7 @@ package ciphersuite -import "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" +import "github.com/pion/dtls/v3/pkg/crypto/clientcertificate" // TLSPskWithAes128GcmSha256 implements the TLS_PSK_WITH_AES_128_GCM_SHA256 CipherSuite type TLSPskWithAes128GcmSha256 struct { diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_256_ccm8.go b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_psk_with_aes_256_ccm8.go similarity index 79% rename from vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_256_ccm8.go rename to vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_psk_with_aes_256_ccm8.go index 32d5030182..211bdae033 100644 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_256_ccm8.go +++ b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/tls_psk_with_aes_256_ccm8.go @@ -4,8 +4,8 @@ package ciphersuite import ( - "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" + "github.com/pion/dtls/v3/pkg/crypto/ciphersuite" + "github.com/pion/dtls/v3/pkg/crypto/clientcertificate" ) // NewTLSPskWithAes256Ccm8 returns the TLS_PSK_WITH_AES_256_CCM_8 CipherSuite diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/types/authentication_type.go b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/types/authentication_type.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/internal/ciphersuite/types/authentication_type.go rename to vendor/github.com/pion/dtls/v3/internal/ciphersuite/types/authentication_type.go diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/types/key_exchange_algorithm.go b/vendor/github.com/pion/dtls/v3/internal/ciphersuite/types/key_exchange_algorithm.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/internal/ciphersuite/types/key_exchange_algorithm.go rename to vendor/github.com/pion/dtls/v3/internal/ciphersuite/types/key_exchange_algorithm.go diff --git a/vendor/github.com/pion/dtls/v2/internal/closer/closer.go b/vendor/github.com/pion/dtls/v3/internal/closer/closer.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/internal/closer/closer.go rename to vendor/github.com/pion/dtls/v3/internal/closer/closer.go diff --git a/vendor/github.com/pion/dtls/v3/internal/net/buffer.go b/vendor/github.com/pion/dtls/v3/internal/net/buffer.go new file mode 100644 index 0000000000..9ab290e4cd --- /dev/null +++ b/vendor/github.com/pion/dtls/v3/internal/net/buffer.go @@ -0,0 +1,235 @@ +// SPDX-FileCopyrightText: 2023 The Pion community +// SPDX-License-Identifier: MIT + +// Package net implements DTLS specific networking primitives. +// NOTE: this package is an adaption of pion/transport/packetio that allows for +// storing a remote address alongside each packet in the buffer and implements +// relevant methods of net.PacketConn. If possible, the updates made in this +// repository will be reflected back upstream. If not, it is likely that this +// will be moved to a public package in this repository. +// +// This package was migrated from pion/transport/packetio at +// https://github.com/pion/transport/commit/6890c795c807a617c054149eee40a69d7fdfbfdb +package net + +import ( + "bytes" + "errors" + "io" + "net" + "sync" + "time" + + "github.com/pion/transport/v3/deadline" +) + +// ErrTimeout indicates that deadline was reached before operation could be +// completed. +var ErrTimeout = errors.New("buffer: i/o timeout") + +// AddrPacket is a packet payload and the associated remote address from which +// it was received. +type AddrPacket struct { + addr net.Addr + data bytes.Buffer +} + +// PacketBuffer is a circular buffer for network packets. Each slot in the +// buffer contains the remote address from which the packet was received, as +// well as the packet data. +type PacketBuffer struct { + mutex sync.Mutex + + packets []AddrPacket + write, read int + + // full indicates whether the buffer is full, which is needed to distinguish + // when the write pointer and read pointer are at the same index. + full bool + + notify chan struct{} + closed bool + + readDeadline *deadline.Deadline +} + +// NewPacketBuffer creates a new PacketBuffer. +func NewPacketBuffer() *PacketBuffer { + return &PacketBuffer{ + readDeadline: deadline.New(), + // In the narrow context in which this package is currently used, there + // will always be at least one packet written to the buffer. Therefore, + // we opt to allocate with size of 1 during construction, rather than + // waiting until that first packet is written. + packets: make([]AddrPacket, 1), + full: false, + } +} + +// WriteTo writes a single packet to the buffer. The supplied address will +// remain associated with the packet. +func (b *PacketBuffer) WriteTo(p []byte, addr net.Addr) (int, error) { + b.mutex.Lock() + + if b.closed { + b.mutex.Unlock() + return 0, io.ErrClosedPipe + } + + var notify chan struct{} + if b.notify != nil { + notify = b.notify + b.notify = nil + } + + // Check to see if we are full. + if b.full { + // If so, grow AddrPacket buffer. + var newSize int + if len(b.packets) < 128 { + // Double the number of packets. + newSize = len(b.packets) * 2 + } else { + // Increase the number of packets by 25%. + newSize = 5 * len(b.packets) / 4 + } + newBuf := make([]AddrPacket, newSize) + var n int + if b.read < b.write { + n = copy(newBuf, b.packets[b.read:b.write]) + } else { + n = copy(newBuf, b.packets[b.read:]) + n += copy(newBuf[n:], b.packets[:b.write]) + } + + b.packets = newBuf + + // Update write pointer to point to new location and mark buffer as not + // full. + b.write = n + b.full = false + } + + // Store the packet at the write pointer. + packet := &b.packets[b.write] + packet.data.Reset() + n, err := packet.data.Write(p) + if err != nil { + b.mutex.Unlock() + return n, err + } + packet.addr = addr + + // Increment write pointer. + b.write++ + + // If the write pointer is equal to the length of the buffer, wrap around. + if len(b.packets) == b.write { + b.write = 0 + } + + // If a write resulted in making write and read pointers equivalent, then we + // are full. + if b.write == b.read { + b.full = true + } + + b.mutex.Unlock() + + if notify != nil { + close(notify) + } + + return n, nil +} + +// ReadFrom reads a single packet from the buffer, or blocks until one is +// available. +func (b *PacketBuffer) ReadFrom(packet []byte) (n int, addr net.Addr, err error) { + select { + case <-b.readDeadline.Done(): + return 0, nil, ErrTimeout + default: + } + + for { + b.mutex.Lock() + + if b.read != b.write || b.full { + ap := b.packets[b.read] + if len(packet) < ap.data.Len() { + b.mutex.Unlock() + return 0, nil, io.ErrShortBuffer + } + + // Copy packet data from buffer. + n, err := ap.data.Read(packet) + if err != nil { + b.mutex.Unlock() + return n, nil, err + } + + // Advance read pointer. + b.read++ + if len(b.packets) == b.read { + b.read = 0 + } + + // If we were full before reading and have successfully read, we are + // no longer full. + if b.full { + b.full = false + } + + b.mutex.Unlock() + + return n, ap.addr, nil + } + + if b.closed { + b.mutex.Unlock() + return 0, nil, io.EOF + } + + if b.notify == nil { + b.notify = make(chan struct{}) + } + notify := b.notify + b.mutex.Unlock() + + select { + case <-b.readDeadline.Done(): + return 0, nil, ErrTimeout + case <-notify: + } + } +} + +// Close closes the buffer, allowing unread packets to be read, but erroring on +// any new writes. +func (b *PacketBuffer) Close() (err error) { + b.mutex.Lock() + + if b.closed { + b.mutex.Unlock() + return nil + } + + notify := b.notify + b.notify = nil + b.closed = true + + b.mutex.Unlock() + + if notify != nil { + close(notify) + } + + return nil +} + +// SetReadDeadline sets the read deadline for the buffer. +func (b *PacketBuffer) SetReadDeadline(t time.Time) error { + b.readDeadline.Set(t) + return nil +} diff --git a/vendor/github.com/pion/dtls/v3/internal/net/udp/packet_conn.go b/vendor/github.com/pion/dtls/v3/internal/net/udp/packet_conn.go new file mode 100644 index 0000000000..da5b6fae8c --- /dev/null +++ b/vendor/github.com/pion/dtls/v3/internal/net/udp/packet_conn.go @@ -0,0 +1,407 @@ +// SPDX-FileCopyrightText: 2023 The Pion community +// SPDX-License-Identifier: MIT + +// Package udp implements DTLS specific UDP networking primitives. +// NOTE: this package is an adaption of pion/transport/udp that allows for +// routing datagrams based on identifiers other than the remote address. The +// primary use case for this functionality is routing based on DTLS connection +// IDs. In order to allow for consumers of this package to treat connections as +// generic net.PackageConn, routing and identitier establishment is based on +// custom introspecion of datagrams, rather than direct intervention by +// consumers. If possible, the updates made in this repository will be reflected +// back upstream. If not, it is likely that this will be moved to a public +// package in this repository. +// +// This package was migrated from pion/transport/udp at +// https://github.com/pion/transport/commit/6890c795c807a617c054149eee40a69d7fdfbfdb +package udp + +import ( + "context" + "errors" + "net" + "sync" + "sync/atomic" + "time" + + idtlsnet "github.com/pion/dtls/v3/internal/net" + dtlsnet "github.com/pion/dtls/v3/pkg/net" + "github.com/pion/transport/v3/deadline" +) + +const ( + receiveMTU = 8192 + defaultListenBacklog = 128 // same as Linux default +) + +// Typed errors +var ( + ErrClosedListener = errors.New("udp: listener closed") + ErrListenQueueExceeded = errors.New("udp: listen queue exceeded") +) + +// listener augments a connection-oriented Listener over a UDP PacketConn +type listener struct { + pConn *net.UDPConn + + accepting atomic.Value // bool + acceptCh chan *PacketConn + doneCh chan struct{} + doneOnce sync.Once + acceptFilter func([]byte) bool + datagramRouter func([]byte) (string, bool) + connIdentifier func([]byte) (string, bool) + + connLock sync.Mutex + conns map[string]*PacketConn + connWG sync.WaitGroup + + readWG sync.WaitGroup + errClose atomic.Value // error + + readDoneCh chan struct{} + errRead atomic.Value // error +} + +// Accept waits for and returns the next connection to the listener. +func (l *listener) Accept() (net.PacketConn, net.Addr, error) { + select { + case c := <-l.acceptCh: + l.connWG.Add(1) + return c, c.raddr, nil + + case <-l.readDoneCh: + err, _ := l.errRead.Load().(error) + return nil, nil, err + + case <-l.doneCh: + return nil, nil, ErrClosedListener + } +} + +// Close closes the listener. +// Any blocked Accept operations will be unblocked and return errors. +func (l *listener) Close() error { + var err error + l.doneOnce.Do(func() { + l.accepting.Store(false) + close(l.doneCh) + + l.connLock.Lock() + // Close unaccepted connections + lclose: + for { + select { + case c := <-l.acceptCh: + close(c.doneCh) + // If we have an alternate identifier, remove it from the connection + // map. + if id := c.id.Load(); id != nil { + delete(l.conns, id.(string)) //nolint:forcetypeassert + } + // If we haven't already removed the remote address, remove it + // from the connection map. + if c.rmraddr.Load() == nil { + delete(l.conns, c.raddr.String()) + c.rmraddr.Store(true) + } + default: + break lclose + } + } + nConns := len(l.conns) + l.connLock.Unlock() + + l.connWG.Done() + + if nConns == 0 { + // Wait if this is the final connection. + l.readWG.Wait() + if errClose, ok := l.errClose.Load().(error); ok { + err = errClose + } + } else { + err = nil + } + }) + + return err +} + +// Addr returns the listener's network address. +func (l *listener) Addr() net.Addr { + return l.pConn.LocalAddr() +} + +// ListenConfig stores options for listening to an address. +type ListenConfig struct { + // Backlog defines the maximum length of the queue of pending + // connections. It is equivalent of the backlog argument of + // POSIX listen function. + // If a connection request arrives when the queue is full, + // the request will be silently discarded, unlike TCP. + // Set zero to use default value 128 which is same as Linux default. + Backlog int + + // AcceptFilter determines whether the new conn should be made for + // the incoming packet. If not set, any packet creates new conn. + AcceptFilter func([]byte) bool + + // DatagramRouter routes an incoming datagram to a connection by extracting + // an identifier from the its paylod + DatagramRouter func([]byte) (string, bool) + + // ConnectionIdentifier extracts an identifier from an outgoing packet. If + // the identifier is not already associated with the connection, it will be + // added. + ConnectionIdentifier func([]byte) (string, bool) +} + +// Listen creates a new listener based on the ListenConfig. +func (lc *ListenConfig) Listen(network string, laddr *net.UDPAddr) (dtlsnet.PacketListener, error) { + if lc.Backlog == 0 { + lc.Backlog = defaultListenBacklog + } + + conn, err := net.ListenUDP(network, laddr) + if err != nil { + return nil, err + } + + l := &listener{ + pConn: conn, + acceptCh: make(chan *PacketConn, lc.Backlog), + conns: make(map[string]*PacketConn), + doneCh: make(chan struct{}), + acceptFilter: lc.AcceptFilter, + datagramRouter: lc.DatagramRouter, + connIdentifier: lc.ConnectionIdentifier, + readDoneCh: make(chan struct{}), + } + + l.accepting.Store(true) + l.connWG.Add(1) + l.readWG.Add(2) // wait readLoop and Close execution routine + + go l.readLoop() + go func() { + l.connWG.Wait() + if err := l.pConn.Close(); err != nil { + l.errClose.Store(err) + } + l.readWG.Done() + }() + + return l, nil +} + +// Listen creates a new listener using default ListenConfig. +func Listen(network string, laddr *net.UDPAddr) (dtlsnet.PacketListener, error) { + return (&ListenConfig{}).Listen(network, laddr) +} + +// readLoop dispatches packets to the proper connection, creating a new one if +// necessary, until all connections are closed. +func (l *listener) readLoop() { + defer l.readWG.Done() + defer close(l.readDoneCh) + + buf := make([]byte, receiveMTU) + + for { + n, raddr, err := l.pConn.ReadFrom(buf) + if err != nil { + l.errRead.Store(err) + return + } + conn, ok, err := l.getConn(raddr, buf[:n]) + if err != nil { + continue + } + if ok { + _, _ = conn.buffer.WriteTo(buf[:n], raddr) + } + } +} + +// getConn gets an existing connection or creates a new one. +func (l *listener) getConn(raddr net.Addr, buf []byte) (*PacketConn, bool, error) { + l.connLock.Lock() + defer l.connLock.Unlock() + // If we have a custom resolver, use it. + if l.datagramRouter != nil { + if id, ok := l.datagramRouter(buf); ok { + if conn, ok := l.conns[id]; ok { + return conn, true, nil + } + } + } + + // If we don't have a custom resolver, or we were unable to find an + // associated connection, fall back to remote address. + conn, ok := l.conns[raddr.String()] + if !ok { + if isAccepting, ok := l.accepting.Load().(bool); !isAccepting || !ok { + return nil, false, ErrClosedListener + } + if l.acceptFilter != nil { + if !l.acceptFilter(buf) { + return nil, false, nil + } + } + conn = l.newPacketConn(raddr) + select { + case l.acceptCh <- conn: + l.conns[raddr.String()] = conn + default: + return nil, false, ErrListenQueueExceeded + } + } + return conn, true, nil +} + +// PacketConn is a net.PacketConn implementation that is able to dictate its +// routing ID via an alternate identifier from its remote address. Internal +// buffering is performed for reads, and writes are passed through to the +// underlying net.PacketConn. +type PacketConn struct { + listener *listener + + raddr net.Addr + rmraddr atomic.Value // bool + id atomic.Value // string + + buffer *idtlsnet.PacketBuffer + + doneCh chan struct{} + doneOnce sync.Once + + writeDeadline *deadline.Deadline +} + +// newPacketConn constructs a new PacketConn. +func (l *listener) newPacketConn(raddr net.Addr) *PacketConn { + return &PacketConn{ + listener: l, + raddr: raddr, + buffer: idtlsnet.NewPacketBuffer(), + doneCh: make(chan struct{}), + writeDeadline: deadline.New(), + } +} + +// ReadFrom reads a single packet payload and its associated remote address from +// the underlying buffer. +func (c *PacketConn) ReadFrom(p []byte) (int, net.Addr, error) { + return c.buffer.ReadFrom(p) +} + +// WriteTo writes len(p) bytes from p to the specified address. +func (c *PacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) { + // If we have a connection identifier, check to see if the outgoing packet + // sets it. + if c.listener.connIdentifier != nil { + id := c.id.Load() + // Only update establish identifier if we haven't already done so. + if id == nil { + candidate, ok := c.listener.connIdentifier(p) + // If we have an identifier, add entry to connection map. + if ok { + c.listener.connLock.Lock() + c.listener.conns[candidate] = c + c.listener.connLock.Unlock() + c.id.Store(candidate) + } + } + // If we are writing to a remote address that differs from the initial, + // we have an alternate identifier established, and we haven't already + // freed the remote address, free the remote address to be used by + // another connection. + // Note: this strategy results in holding onto a remote address after it + // is potentially no longer in use by the client. However, releasing + // earlier means that we could miss some packets that should have been + // routed to this connection. Ideally, we would drop the connection + // entry for the remote address as soon as the client starts sending + // using an alternate identifier, but in practice this proves + // challenging because any client could spoof a connection identifier, + // resulting in the remote address entry being dropped prior to the + // "real" client transitioning to sending using the alternate + // identifier. + if id != nil && c.rmraddr.Load() == nil && addr.String() != c.raddr.String() { + c.listener.connLock.Lock() + delete(c.listener.conns, c.raddr.String()) + c.rmraddr.Store(true) + c.listener.connLock.Unlock() + } + } + + select { + case <-c.writeDeadline.Done(): + return 0, context.DeadlineExceeded + default: + } + return c.listener.pConn.WriteTo(p, addr) +} + +// Close closes the conn and releases any Read calls +func (c *PacketConn) Close() error { + var err error + c.doneOnce.Do(func() { + c.listener.connWG.Done() + close(c.doneCh) + c.listener.connLock.Lock() + // If we have an alternate identifier, remove it from the connection + // map. + if id := c.id.Load(); id != nil { + delete(c.listener.conns, id.(string)) //nolint:forcetypeassert + } + // If we haven't already removed the remote address, remove it from the + // connection map. + if c.rmraddr.Load() == nil { + delete(c.listener.conns, c.raddr.String()) + c.rmraddr.Store(true) + } + nConns := len(c.listener.conns) + c.listener.connLock.Unlock() + + if isAccepting, ok := c.listener.accepting.Load().(bool); nConns == 0 && !isAccepting && ok { + // Wait if this is the final connection + c.listener.readWG.Wait() + if errClose, ok := c.listener.errClose.Load().(error); ok { + err = errClose + } + } else { + err = nil + } + + if errBuf := c.buffer.Close(); errBuf != nil && err == nil { + err = errBuf + } + }) + + return err +} + +// LocalAddr implements net.PacketConn.LocalAddr. +func (c *PacketConn) LocalAddr() net.Addr { + return c.listener.pConn.LocalAddr() +} + +// SetDeadline implements net.PacketConn.SetDeadline. +func (c *PacketConn) SetDeadline(t time.Time) error { + c.writeDeadline.Set(t) + return c.SetReadDeadline(t) +} + +// SetReadDeadline implements net.PacketConn.SetReadDeadline. +func (c *PacketConn) SetReadDeadline(t time.Time) error { + return c.buffer.SetReadDeadline(t) +} + +// SetWriteDeadline implements net.PacketConn.SetWriteDeadline. +func (c *PacketConn) SetWriteDeadline(t time.Time) error { + c.writeDeadline.Set(t) + // Write deadline of underlying connection should not be changed + // since the connection can be shared. + return nil +} diff --git a/vendor/github.com/pion/dtls/v2/internal/util/util.go b/vendor/github.com/pion/dtls/v3/internal/util/util.go similarity index 72% rename from vendor/github.com/pion/dtls/v2/internal/util/util.go rename to vendor/github.com/pion/dtls/v3/internal/util/util.go index 685910fc21..382a0e1cdd 100644 --- a/vendor/github.com/pion/dtls/v2/internal/util/util.go +++ b/vendor/github.com/pion/dtls/v3/internal/util/util.go @@ -6,6 +6,8 @@ package util import ( "encoding/binary" + + "golang.org/x/crypto/cryptobyte" ) // BigEndianUint24 returns the value of a big endian uint24 @@ -40,3 +42,10 @@ func Max(a, b int) int { } return b } + +// AddUint48 appends a big-endian, 48-bit value to the byte string. +// Remove if / when https://github.com/golang/crypto/pull/265 is merged +// upstream. +func AddUint48(b *cryptobyte.Builder, v uint64) { + b.AddBytes([]byte{byte(v >> 40), byte(v >> 32), byte(v >> 24), byte(v >> 16), byte(v >> 8), byte(v)}) +} diff --git a/vendor/github.com/pion/dtls/v2/listener.go b/vendor/github.com/pion/dtls/v3/listener.go similarity index 72% rename from vendor/github.com/pion/dtls/v2/listener.go rename to vendor/github.com/pion/dtls/v3/listener.go index 190d236c72..22e56ce520 100644 --- a/vendor/github.com/pion/dtls/v2/listener.go +++ b/vendor/github.com/pion/dtls/v3/listener.go @@ -6,9 +6,10 @@ package dtls import ( "net" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" - "github.com/pion/transport/v2/udp" + "github.com/pion/dtls/v3/internal/net/udp" + dtlsnet "github.com/pion/dtls/v3/pkg/net" + "github.com/pion/dtls/v3/pkg/protocol" + "github.com/pion/dtls/v3/pkg/protocol/recordlayer" ) // Listen creates a DTLS listener @@ -30,6 +31,12 @@ func Listen(network string, laddr *net.UDPAddr, config *Config) (net.Listener, e return h.ContentType == protocol.ContentTypeHandshake }, } + // If connection ID support is enabled, then they must be supported in + // routing. + if config.ConnectionIDGenerator != nil { + lc.DatagramRouter = cidDatagramRouter(len(config.ConnectionIDGenerator())) + lc.ConnectionIdentifier = cidConnIdentifier() + } parent, err := lc.Listen(network, laddr) if err != nil { return nil, err @@ -41,7 +48,7 @@ func Listen(network string, laddr *net.UDPAddr, config *Config) (net.Listener, e } // NewListener creates a DTLS listener which accepts connections from an inner Listener. -func NewListener(inner net.Listener, config *Config) (net.Listener, error) { +func NewListener(inner dtlsnet.PacketListener, config *Config) (net.Listener, error) { if err := validateConfig(config); err != nil { return nil, err } @@ -55,19 +62,17 @@ func NewListener(inner net.Listener, config *Config) (net.Listener, error) { // listener represents a DTLS listener type listener struct { config *Config - parent net.Listener + parent dtlsnet.PacketListener } // Accept waits for and returns the next connection to the listener. // You have to either close or read on all connection that are created. -// Connection handshake will timeout using ConnectContextMaker in the Config. -// If you want to specify the timeout duration, set ConnectContextMaker. func (l *listener) Accept() (net.Conn, error) { - c, err := l.parent.Accept() + c, raddr, err := l.parent.Accept() if err != nil { return nil, err } - return Server(c, l.config) + return Server(c, raddr, l.config) } // Close closes the listener. diff --git a/vendor/github.com/pion/dtls/v2/packet.go b/vendor/github.com/pion/dtls/v3/packet.go similarity index 72% rename from vendor/github.com/pion/dtls/v2/packet.go rename to vendor/github.com/pion/dtls/v3/packet.go index 55d6272eec..c224eff1bd 100644 --- a/vendor/github.com/pion/dtls/v2/packet.go +++ b/vendor/github.com/pion/dtls/v3/packet.go @@ -3,10 +3,13 @@ package dtls -import "github.com/pion/dtls/v2/pkg/protocol/recordlayer" +import ( + "github.com/pion/dtls/v3/pkg/protocol/recordlayer" +) type packet struct { record *recordlayer.RecordLayer shouldEncrypt bool + shouldWrapCID bool resetLocalSequenceNumber bool } diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/ccm/ccm.go b/vendor/github.com/pion/dtls/v3/pkg/crypto/ccm/ccm.go similarity index 97% rename from vendor/github.com/pion/dtls/v2/pkg/crypto/ccm/ccm.go rename to vendor/github.com/pion/dtls/v3/pkg/crypto/ccm/ccm.go index d6e6fc479f..73476f219e 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/crypto/ccm/ccm.go +++ b/vendor/github.com/pion/dtls/v3/pkg/crypto/ccm/ccm.go @@ -74,14 +74,14 @@ func (c *ccm) Overhead() int { return int(c.M) } func (c *ccm) MaxLength() int { return maxlen(c.L, c.Overhead()) } func maxlen(l uint8, tagsize int) int { - max := (uint64(1) << (8 * l)) - 1 - if m64 := uint64(math.MaxInt64) - uint64(tagsize); l > 8 || max > m64 { - max = m64 // The maximum lentgh on a 64bit arch + mLen := (uint64(1) << (8 * l)) - 1 + if m64 := uint64(math.MaxInt64) - uint64(tagsize); l > 8 || mLen > m64 { + mLen = m64 // The maximum lentgh on a 64bit arch } - if max != uint64(int(max)) { + if mLen != uint64(int(mLen)) { return math.MaxInt32 - tagsize // We have only 32bit int's } - return int(max) + return int(mLen) } // MaxNonceLength returns the maximum nonce length for a given plaintext length. diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/cbc.go b/vendor/github.com/pion/dtls/v3/pkg/crypto/ciphersuite/cbc.go similarity index 61% rename from vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/cbc.go rename to vendor/github.com/pion/dtls/v3/pkg/crypto/ciphersuite/cbc.go index 460fb14379..68a080d5dc 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/cbc.go +++ b/vendor/github.com/pion/dtls/v3/pkg/crypto/ciphersuite/cbc.go @@ -11,10 +11,11 @@ import ( //nolint:gci "encoding/binary" "hash" - "github.com/pion/dtls/v2/internal/util" - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" + "github.com/pion/dtls/v3/internal/util" + "github.com/pion/dtls/v3/pkg/crypto/prf" + "github.com/pion/dtls/v3/pkg/protocol" + "github.com/pion/dtls/v3/pkg/protocol/recordlayer" + "golang.org/x/crypto/cryptobyte" ) // block ciphers using cipher block chaining. @@ -64,18 +65,24 @@ func NewCBC(localKey, localWriteIV, localMac, remoteKey, remoteWriteIV, remoteMa // Encrypt encrypt a DTLS RecordLayer message func (c *CBC) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) { - payload := raw[recordlayer.HeaderSize:] - raw = raw[:recordlayer.HeaderSize] + payload := raw[pkt.Header.Size():] + raw = raw[:pkt.Header.Size()] blockSize := c.writeCBC.BlockSize() // Generate + Append MAC h := pkt.Header - MAC, err := c.hmac(h.Epoch, h.SequenceNumber, h.ContentType, h.Version, payload, c.writeMac, c.h) + var err error + var mac []byte + if h.ContentType == protocol.ContentTypeConnectionID { + mac, err = c.hmacCID(h.Epoch, h.SequenceNumber, h.Version, payload, c.writeMac, c.h, h.ConnectionID) + } else { + mac, err = c.hmac(h.Epoch, h.SequenceNumber, h.ContentType, h.Version, payload, c.writeMac, c.h) + } if err != nil { return nil, err } - payload = append(payload, MAC...) + payload = append(payload, mac...) // Generate + Append padding padding := make([]byte, blockSize-len(payload)%blockSize) @@ -96,26 +103,26 @@ func (c *CBC) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) c.writeCBC.CryptBlocks(payload, payload) payload = append(iv, payload...) - // Prepend unencrypte header with encrypted payload + // Prepend unencrypted header with encrypted payload raw = append(raw, payload...) // Update recordLayer size to include IV+MAC+Padding - binary.BigEndian.PutUint16(raw[recordlayer.HeaderSize-2:], uint16(len(raw)-recordlayer.HeaderSize)) + binary.BigEndian.PutUint16(raw[pkt.Header.Size()-2:], uint16(len(raw)-pkt.Header.Size())) return raw, nil } // Decrypt decrypts a DTLS RecordLayer message -func (c *CBC) Decrypt(in []byte) ([]byte, error) { - body := in[recordlayer.HeaderSize:] +func (c *CBC) Decrypt(h recordlayer.Header, in []byte) ([]byte, error) { blockSize := c.readCBC.BlockSize() mac := c.h() - var h recordlayer.Header - err := h.Unmarshal(in) - switch { - case err != nil: + if err := h.Unmarshal(in); err != nil { return nil, err + } + body := in[h.Size():] + + switch { case h.ContentType == protocol.ContentTypeChangeCipherSpec: // Nothing to encrypt with ChangeCipherSpec return in, nil @@ -145,14 +152,19 @@ func (c *CBC) Decrypt(in []byte) ([]byte, error) { dataEnd := len(body) - macSize - paddingLen expectedMAC := body[dataEnd : dataEnd+macSize] - actualMAC, err := c.hmac(h.Epoch, h.SequenceNumber, h.ContentType, h.Version, body[:dataEnd], c.readMac, c.h) - + var err error + var actualMAC []byte + if h.ContentType == protocol.ContentTypeConnectionID { + actualMAC, err = c.hmacCID(h.Epoch, h.SequenceNumber, h.Version, body[:dataEnd], c.readMac, c.h, h.ConnectionID) + } else { + actualMAC, err = c.hmac(h.Epoch, h.SequenceNumber, h.ContentType, h.Version, body[:dataEnd], c.readMac, c.h) + } // Compute Local MAC and compare if err != nil || !hmac.Equal(actualMAC, expectedMAC) { return nil, errInvalidMAC } - return append(in[:recordlayer.HeaderSize], body[:dataEnd]...), nil + return append(in[:h.Size()], body[:dataEnd]...), nil } func (c *CBC) hmac(epoch uint16, sequenceNumber uint64, contentType protocol.ContentType, protocolVersion protocol.Version, payload []byte, key []byte, hf func() hash.Hash) ([]byte, error) { @@ -169,7 +181,45 @@ func (c *CBC) hmac(epoch uint16, sequenceNumber uint64, contentType protocol.Con if _, err := h.Write(msg); err != nil { return nil, err - } else if _, err := h.Write(payload); err != nil { + } + if _, err := h.Write(payload); err != nil { + return nil, err + } + + return h.Sum(nil), nil +} + +// hmacCID calculates a MAC according to +// https://datatracker.ietf.org/doc/html/rfc9146#section-5.1 +func (c *CBC) hmacCID(epoch uint16, sequenceNumber uint64, protocolVersion protocol.Version, payload []byte, key []byte, hf func() hash.Hash, cid []byte) ([]byte, error) { + // Must unmarshal inner plaintext in orde to perform MAC. + ip := &recordlayer.InnerPlaintext{} + if err := ip.Unmarshal(payload); err != nil { + return nil, err + } + + h := hmac.New(hf, key) + + var msg cryptobyte.Builder + + msg.AddUint64(seqNumPlaceholder) + msg.AddUint8(uint8(protocol.ContentTypeConnectionID)) + msg.AddUint8(uint8(len(cid))) + msg.AddUint8(uint8(protocol.ContentTypeConnectionID)) + msg.AddUint8(protocolVersion.Major) + msg.AddUint8(protocolVersion.Minor) + msg.AddUint16(epoch) + util.AddUint48(&msg, sequenceNumber) + msg.AddBytes(cid) + msg.AddUint16(uint16(len(payload))) + msg.AddBytes(ip.Content) + msg.AddUint8(uint8(ip.RealType)) + msg.AddBytes(make([]byte, ip.Zeros)) + + if _, err := h.Write(msg.BytesOrPanic()); err != nil { + return nil, err + } + if _, err := h.Write(payload); err != nil { return nil, err } diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/ccm.go b/vendor/github.com/pion/dtls/v3/pkg/crypto/ciphersuite/ccm.go similarity index 66% rename from vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/ccm.go rename to vendor/github.com/pion/dtls/v3/pkg/crypto/ciphersuite/ccm.go index 24050dc926..4c296e2bbd 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/ccm.go +++ b/vendor/github.com/pion/dtls/v3/pkg/crypto/ciphersuite/ccm.go @@ -9,9 +9,9 @@ import ( "encoding/binary" "fmt" - "github.com/pion/dtls/v2/pkg/crypto/ccm" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" + "github.com/pion/dtls/v3/pkg/crypto/ccm" + "github.com/pion/dtls/v3/pkg/protocol" + "github.com/pion/dtls/v3/pkg/protocol/recordlayer" ) // CCMTagLen is the length of Authentication Tag @@ -62,46 +62,56 @@ func NewCCM(tagLen CCMTagLen, localKey, localWriteIV, remoteKey, remoteWriteIV [ // Encrypt encrypt a DTLS RecordLayer message func (c *CCM) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) { - payload := raw[recordlayer.HeaderSize:] - raw = raw[:recordlayer.HeaderSize] + payload := raw[pkt.Header.Size():] + raw = raw[:pkt.Header.Size()] nonce := append(append([]byte{}, c.localWriteIV[:4]...), make([]byte, 8)...) if _, err := rand.Read(nonce[4:]); err != nil { return nil, err } - additionalData := generateAEADAdditionalData(&pkt.Header, len(payload)) + var additionalData []byte + if pkt.Header.ContentType == protocol.ContentTypeConnectionID { + additionalData = generateAEADAdditionalDataCID(&pkt.Header, len(payload)) + } else { + additionalData = generateAEADAdditionalData(&pkt.Header, len(payload)) + } encryptedPayload := c.localCCM.Seal(nil, nonce, payload, additionalData) encryptedPayload = append(nonce[4:], encryptedPayload...) raw = append(raw, encryptedPayload...) // Update recordLayer size to include explicit nonce - binary.BigEndian.PutUint16(raw[recordlayer.HeaderSize-2:], uint16(len(raw)-recordlayer.HeaderSize)) + binary.BigEndian.PutUint16(raw[pkt.Header.Size()-2:], uint16(len(raw)-pkt.Header.Size())) return raw, nil } // Decrypt decrypts a DTLS RecordLayer message -func (c *CCM) Decrypt(in []byte) ([]byte, error) { - var h recordlayer.Header - err := h.Unmarshal(in) - switch { - case err != nil: +func (c *CCM) Decrypt(h recordlayer.Header, in []byte) ([]byte, error) { + if err := h.Unmarshal(in); err != nil { return nil, err + } + switch { case h.ContentType == protocol.ContentTypeChangeCipherSpec: // Nothing to encrypt with ChangeCipherSpec return in, nil - case len(in) <= (8 + recordlayer.HeaderSize): + case len(in) <= (8 + h.Size()): return nil, errNotEnoughRoomForNonce } - nonce := append(append([]byte{}, c.remoteWriteIV[:4]...), in[recordlayer.HeaderSize:recordlayer.HeaderSize+8]...) - out := in[recordlayer.HeaderSize+8:] + nonce := append(append([]byte{}, c.remoteWriteIV[:4]...), in[h.Size():h.Size()+8]...) + out := in[h.Size()+8:] - additionalData := generateAEADAdditionalData(&h, len(out)-int(c.tagLen)) + var additionalData []byte + if h.ContentType == protocol.ContentTypeConnectionID { + additionalData = generateAEADAdditionalDataCID(&h, len(out)-int(c.tagLen)) + } else { + additionalData = generateAEADAdditionalData(&h, len(out)-int(c.tagLen)) + } + var err error out, err = c.remoteCCM.Open(out[:0], nonce, out, additionalData) if err != nil { return nil, fmt.Errorf("%w: %v", errDecryptPacket, err) //nolint:errorlint } - return append(in[:recordlayer.HeaderSize], out...), nil + return append(in[:h.Size()], out...), nil } diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/ciphersuite.go b/vendor/github.com/pion/dtls/v3/pkg/crypto/ciphersuite/ciphersuite.go similarity index 73% rename from vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/ciphersuite.go rename to vendor/github.com/pion/dtls/v3/pkg/crypto/ciphersuite/ciphersuite.go index 9d9fb7418c..90ddf61051 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/ciphersuite.go +++ b/vendor/github.com/pion/dtls/v3/pkg/crypto/ciphersuite/ciphersuite.go @@ -8,8 +8,16 @@ import ( "encoding/binary" "errors" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" + "github.com/pion/dtls/v3/internal/util" + "github.com/pion/dtls/v3/pkg/protocol" + "github.com/pion/dtls/v3/pkg/protocol/recordlayer" + "golang.org/x/crypto/cryptobyte" +) + +const ( + // 8 bytes of 0xff. + // https://datatracker.ietf.org/doc/html/rfc9146#name-record-payload-protection + seqNumPlaceholder = 0xffffffffffffffff ) var ( @@ -21,6 +29,7 @@ var ( func generateAEADAdditionalData(h *recordlayer.Header, payloadLen int) []byte { var additionalData [13]byte + // SequenceNumber MUST be set first // we only want uint48, clobbering an extra 2 (using uint64, Golang doesn't have uint48) binary.BigEndian.PutUint64(additionalData[:], h.SequenceNumber) @@ -33,6 +42,25 @@ func generateAEADAdditionalData(h *recordlayer.Header, payloadLen int) []byte { return additionalData[:] } +// generateAEADAdditionalDataCID generates additional data for AEAD ciphers +// according to https://datatracker.ietf.org/doc/html/rfc9146#name-aead-ciphers +func generateAEADAdditionalDataCID(h *recordlayer.Header, payloadLen int) []byte { + var b cryptobyte.Builder + + b.AddUint64(seqNumPlaceholder) + b.AddUint8(uint8(protocol.ContentTypeConnectionID)) + b.AddUint8(uint8(len(h.ConnectionID))) + b.AddUint8(uint8(protocol.ContentTypeConnectionID)) + b.AddUint8(h.Version.Major) + b.AddUint8(h.Version.Minor) + b.AddUint16(h.Epoch) + util.AddUint48(&b, h.SequenceNumber) + b.AddBytes(h.ConnectionID) + b.AddUint16(uint16(payloadLen)) + + return b.BytesOrPanic() +} + // examinePadding returns, in constant time, the length of the padding to remove // from the end of payload. It also returns a byte which is equal to 255 if the // padding was valid and 0 otherwise. See RFC 2246, Section 6.2.3.2. diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/gcm.go b/vendor/github.com/pion/dtls/v3/pkg/crypto/ciphersuite/gcm.go similarity index 68% rename from vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/gcm.go rename to vendor/github.com/pion/dtls/v3/pkg/crypto/ciphersuite/gcm.go index c0fd1f76f9..a7f8282460 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/gcm.go +++ b/vendor/github.com/pion/dtls/v3/pkg/crypto/ciphersuite/gcm.go @@ -10,8 +10,8 @@ import ( "encoding/binary" "fmt" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" + "github.com/pion/dtls/v3/pkg/protocol" + "github.com/pion/dtls/v3/pkg/protocol/recordlayer" ) const ( @@ -55,8 +55,8 @@ func NewGCM(localKey, localWriteIV, remoteKey, remoteWriteIV []byte) (*GCM, erro // Encrypt encrypt a DTLS RecordLayer message func (g *GCM) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) { - payload := raw[recordlayer.HeaderSize:] - raw = raw[:recordlayer.HeaderSize] + payload := raw[pkt.Header.Size():] + raw = raw[:pkt.Header.Size()] nonce := make([]byte, gcmNonceLength) copy(nonce, g.localWriteIV[:4]) @@ -64,7 +64,12 @@ func (g *GCM) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) return nil, err } - additionalData := generateAEADAdditionalData(&pkt.Header, len(payload)) + var additionalData []byte + if pkt.Header.ContentType == protocol.ContentTypeConnectionID { + additionalData = generateAEADAdditionalDataCID(&pkt.Header, len(payload)) + } else { + additionalData = generateAEADAdditionalData(&pkt.Header, len(payload)) + } encryptedPayload := g.localGCM.Seal(nil, nonce, payload, additionalData) r := make([]byte, len(raw)+len(nonce[4:])+len(encryptedPayload)) copy(r, raw) @@ -72,13 +77,12 @@ func (g *GCM) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) copy(r[len(raw)+len(nonce[4:]):], encryptedPayload) // Update recordLayer size to include explicit nonce - binary.BigEndian.PutUint16(r[recordlayer.HeaderSize-2:], uint16(len(r)-recordlayer.HeaderSize)) + binary.BigEndian.PutUint16(r[pkt.Header.Size()-2:], uint16(len(r)-pkt.Header.Size())) return r, nil } // Decrypt decrypts a DTLS RecordLayer message -func (g *GCM) Decrypt(in []byte) ([]byte, error) { - var h recordlayer.Header +func (g *GCM) Decrypt(h recordlayer.Header, in []byte) ([]byte, error) { err := h.Unmarshal(in) switch { case err != nil: @@ -86,18 +90,23 @@ func (g *GCM) Decrypt(in []byte) ([]byte, error) { case h.ContentType == protocol.ContentTypeChangeCipherSpec: // Nothing to encrypt with ChangeCipherSpec return in, nil - case len(in) <= (8 + recordlayer.HeaderSize): + case len(in) <= (8 + h.Size()): return nil, errNotEnoughRoomForNonce } nonce := make([]byte, 0, gcmNonceLength) - nonce = append(append(nonce, g.remoteWriteIV[:4]...), in[recordlayer.HeaderSize:recordlayer.HeaderSize+8]...) - out := in[recordlayer.HeaderSize+8:] + nonce = append(append(nonce, g.remoteWriteIV[:4]...), in[h.Size():h.Size()+8]...) + out := in[h.Size()+8:] - additionalData := generateAEADAdditionalData(&h, len(out)-gcmTagLength) + var additionalData []byte + if h.ContentType == protocol.ContentTypeConnectionID { + additionalData = generateAEADAdditionalDataCID(&h, len(out)-gcmTagLength) + } else { + additionalData = generateAEADAdditionalData(&h, len(out)-gcmTagLength) + } out, err = g.remoteGCM.Open(out[:0], nonce, out, additionalData) if err != nil { return nil, fmt.Errorf("%w: %v", errDecryptPacket, err) //nolint:errorlint } - return append(in[:recordlayer.HeaderSize], out...), nil + return append(in[:h.Size()], out...), nil } diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/clientcertificate/client_certificate.go b/vendor/github.com/pion/dtls/v3/pkg/crypto/clientcertificate/client_certificate.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/pkg/crypto/clientcertificate/client_certificate.go rename to vendor/github.com/pion/dtls/v3/pkg/crypto/clientcertificate/client_certificate.go diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/elliptic/elliptic.go b/vendor/github.com/pion/dtls/v3/pkg/crypto/elliptic/elliptic.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/pkg/crypto/elliptic/elliptic.go rename to vendor/github.com/pion/dtls/v3/pkg/crypto/elliptic/elliptic.go diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/fingerprint/fingerprint.go b/vendor/github.com/pion/dtls/v3/pkg/crypto/fingerprint/fingerprint.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/pkg/crypto/fingerprint/fingerprint.go rename to vendor/github.com/pion/dtls/v3/pkg/crypto/fingerprint/fingerprint.go diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/fingerprint/hash.go b/vendor/github.com/pion/dtls/v3/pkg/crypto/fingerprint/hash.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/pkg/crypto/fingerprint/hash.go rename to vendor/github.com/pion/dtls/v3/pkg/crypto/fingerprint/hash.go diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/hash/hash.go b/vendor/github.com/pion/dtls/v3/pkg/crypto/hash/hash.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/pkg/crypto/hash/hash.go rename to vendor/github.com/pion/dtls/v3/pkg/crypto/hash/hash.go diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/prf/prf.go b/vendor/github.com/pion/dtls/v3/pkg/crypto/prf/prf.go similarity index 98% rename from vendor/github.com/pion/dtls/v2/pkg/crypto/prf/prf.go rename to vendor/github.com/pion/dtls/v3/pkg/crypto/prf/prf.go index 6e7b3ecba7..b5ac19f794 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/crypto/prf/prf.go +++ b/vendor/github.com/pion/dtls/v3/pkg/crypto/prf/prf.go @@ -13,8 +13,8 @@ import ( //nolint:gci "hash" "math" - "github.com/pion/dtls/v2/pkg/crypto/elliptic" - "github.com/pion/dtls/v2/pkg/protocol" + "github.com/pion/dtls/v3/pkg/crypto/elliptic" + "github.com/pion/dtls/v3/pkg/protocol" "golang.org/x/crypto/curve25519" ) diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/signature/signature.go b/vendor/github.com/pion/dtls/v3/pkg/crypto/signature/signature.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/pkg/crypto/signature/signature.go rename to vendor/github.com/pion/dtls/v3/pkg/crypto/signature/signature.go diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/signaturehash/errors.go b/vendor/github.com/pion/dtls/v3/pkg/crypto/signaturehash/errors.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/pkg/crypto/signaturehash/errors.go rename to vendor/github.com/pion/dtls/v3/pkg/crypto/signaturehash/errors.go diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/signaturehash/signaturehash.go b/vendor/github.com/pion/dtls/v3/pkg/crypto/signaturehash/signaturehash.go similarity index 96% rename from vendor/github.com/pion/dtls/v2/pkg/crypto/signaturehash/signaturehash.go rename to vendor/github.com/pion/dtls/v3/pkg/crypto/signaturehash/signaturehash.go index 2561accd15..38587768b6 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/crypto/signaturehash/signaturehash.go +++ b/vendor/github.com/pion/dtls/v3/pkg/crypto/signaturehash/signaturehash.go @@ -12,8 +12,8 @@ import ( "crypto/tls" "fmt" - "github.com/pion/dtls/v2/pkg/crypto/hash" - "github.com/pion/dtls/v2/pkg/crypto/signature" + "github.com/pion/dtls/v3/pkg/crypto/hash" + "github.com/pion/dtls/v3/pkg/crypto/signature" ) // Algorithm is a signature/hash algorithm pairs which may be used in diff --git a/vendor/github.com/pion/dtls/v3/pkg/net/net.go b/vendor/github.com/pion/dtls/v3/pkg/net/net.go new file mode 100644 index 0000000000..e76daf56aa --- /dev/null +++ b/vendor/github.com/pion/dtls/v3/pkg/net/net.go @@ -0,0 +1,108 @@ +// SPDX-FileCopyrightText: 2023 The Pion community +// SPDX-License-Identifier: MIT + +// Package net defines packet-oriented primitives that are compatible with net +// in the standard library. +package net + +import ( + "net" + "time" +) + +// A PacketListener is the same as net.Listener but returns a net.PacketConn on +// Accept() rather than a net.Conn. +// +// Multiple goroutines may invoke methods on a PacketListener simultaneously. +type PacketListener interface { + // Accept waits for and returns the next connection to the listener. + Accept() (net.PacketConn, net.Addr, error) + + // Close closes the listener. + // Any blocked Accept operations will be unblocked and return errors. + Close() error + + // Addr returns the listener's network address. + Addr() net.Addr +} + +// PacketListenerFromListener converts a net.Listener into a +// dtlsnet.PacketListener. +func PacketListenerFromListener(l net.Listener) PacketListener { + return &packetListenerWrapper{ + l: l, + } +} + +// packetListenerWrapper wraps a net.Listener and implements +// dtlsnet.PacketListener. +type packetListenerWrapper struct { + l net.Listener +} + +// Accept calls Accept on the underlying net.Listener and converts the returned +// net.Conn into a net.PacketConn. +func (p *packetListenerWrapper) Accept() (net.PacketConn, net.Addr, error) { + c, err := p.l.Accept() + if err != nil { + return PacketConnFromConn(c), nil, err + } + return PacketConnFromConn(c), c.RemoteAddr(), nil +} + +// Close closes the underlying net.Listener. +func (p *packetListenerWrapper) Close() error { + return p.l.Close() +} + +// Addr returns the address of the underlying net.Listener. +func (p *packetListenerWrapper) Addr() net.Addr { + return p.l.Addr() +} + +// PacketConnFromConn converts a net.Conn into a net.PacketConn. +func PacketConnFromConn(conn net.Conn) net.PacketConn { + return &packetConnWrapper{conn} +} + +// packetConnWrapper wraps a net.Conn and implements net.PacketConn. +type packetConnWrapper struct { + conn net.Conn +} + +// ReadFrom reads from the underlying net.Conn and returns its remote address. +func (p *packetConnWrapper) ReadFrom(b []byte) (int, net.Addr, error) { + n, err := p.conn.Read(b) + return n, p.conn.RemoteAddr(), err +} + +// WriteTo writes to the underlying net.Conn. +func (p *packetConnWrapper) WriteTo(b []byte, _ net.Addr) (int, error) { + n, err := p.conn.Write(b) + return n, err +} + +// Close closes the underlying net.Conn. +func (p *packetConnWrapper) Close() error { + return p.conn.Close() +} + +// LocalAddr returns the local address of the underlying net.Conn. +func (p *packetConnWrapper) LocalAddr() net.Addr { + return p.conn.LocalAddr() +} + +// SetDeadline sets the deadline on the underlying net.Conn. +func (p *packetConnWrapper) SetDeadline(t time.Time) error { + return p.conn.SetDeadline(t) +} + +// SetReadDeadline sets the read deadline on the underlying net.Conn. +func (p *packetConnWrapper) SetReadDeadline(t time.Time) error { + return p.conn.SetReadDeadline(t) +} + +// SetWriteDeadline sets the write deadline on the underlying net.Conn. +func (p *packetConnWrapper) SetWriteDeadline(t time.Time) error { + return p.conn.SetWriteDeadline(t) +} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/alert/alert.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/alert/alert.go similarity index 99% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/alert/alert.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/alert/alert.go index 91e9f4d60f..0a9e0a2154 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/alert/alert.go +++ b/vendor/github.com/pion/dtls/v3/pkg/protocol/alert/alert.go @@ -8,7 +8,7 @@ import ( "errors" "fmt" - "github.com/pion/dtls/v2/pkg/protocol" + "github.com/pion/dtls/v3/pkg/protocol" ) var errBufferTooSmall = &protocol.TemporaryError{Err: errors.New("buffer is too small")} //nolint:goerr113 diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/application_data.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/application_data.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/application_data.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/application_data.go diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/change_cipher_spec.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/change_cipher_spec.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/change_cipher_spec.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/change_cipher_spec.go diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/compression_method.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/compression_method.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/compression_method.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/compression_method.go diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/content.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/content.go similarity index 93% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/content.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/content.go index 92c9db2bf4..154005e2c3 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/content.go +++ b/vendor/github.com/pion/dtls/v3/pkg/protocol/content.go @@ -14,6 +14,7 @@ const ( ContentTypeAlert ContentType = 21 ContentTypeHandshake ContentType = 22 ContentTypeApplicationData ContentType = 23 + ContentTypeConnectionID ContentType = 25 ) // Content is the top level distinguisher for a DTLS Datagram diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/errors.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/errors.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/errors.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/errors.go diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/alpn.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/extension/alpn.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/extension/alpn.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/extension/alpn.go diff --git a/vendor/github.com/pion/dtls/v3/pkg/protocol/extension/connection_id.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/extension/connection_id.go new file mode 100644 index 0000000000..b3fe1640f2 --- /dev/null +++ b/vendor/github.com/pion/dtls/v3/pkg/protocol/extension/connection_id.go @@ -0,0 +1,59 @@ +// SPDX-FileCopyrightText: 2023 The Pion community +// SPDX-License-Identifier: MIT + +package extension + +import ( + "golang.org/x/crypto/cryptobyte" +) + +// ConnectionID is a DTLS extension that provides an alternative to IP address +// and port for session association. +// +// https://tools.ietf.org/html/rfc9146 +type ConnectionID struct { + // A zero-length connection ID indicates for a client or server that + // negotiated connection IDs from the peer will be sent but there is no need + // to respond with one + CID []byte // variable length +} + +// TypeValue returns the extension TypeValue +func (c ConnectionID) TypeValue() TypeValue { + return ConnectionIDTypeValue +} + +// Marshal encodes the extension +func (c *ConnectionID) Marshal() ([]byte, error) { + var b cryptobyte.Builder + b.AddUint16(uint16(c.TypeValue())) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(c.CID) + }) + }) + return b.Bytes() +} + +// Unmarshal populates the extension from encoded data +func (c *ConnectionID) Unmarshal(data []byte) error { + val := cryptobyte.String(data) + var extension uint16 + val.ReadUint16(&extension) + if TypeValue(extension) != c.TypeValue() { + return errInvalidExtensionType + } + + var extData cryptobyte.String + val.ReadUint16LengthPrefixed(&extData) + + var cid cryptobyte.String + if !extData.ReadUint8LengthPrefixed(&cid) { + return errInvalidCIDFormat + } + c.CID = make([]byte, len(cid)) + if !cid.CopyBytes(c.CID) { + return errInvalidCIDFormat + } + return nil +} diff --git a/vendor/github.com/pion/dtls/v3/pkg/protocol/extension/errors.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/extension/errors.go new file mode 100644 index 0000000000..5999c96fed --- /dev/null +++ b/vendor/github.com/pion/dtls/v3/pkg/protocol/extension/errors.go @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: 2023 The Pion community +// SPDX-License-Identifier: MIT + +package extension + +import ( + "errors" + + "github.com/pion/dtls/v3/pkg/protocol" +) + +var ( + // ErrALPNInvalidFormat is raised when the ALPN format is invalid + ErrALPNInvalidFormat = &protocol.FatalError{Err: errors.New("invalid alpn format")} //nolint:goerr113 + errALPNNoAppProto = &protocol.FatalError{Err: errors.New("no application protocol")} //nolint:goerr113 + errBufferTooSmall = &protocol.TemporaryError{Err: errors.New("buffer is too small")} //nolint:goerr113 + errInvalidExtensionType = &protocol.FatalError{Err: errors.New("invalid extension type")} //nolint:goerr113 + errInvalidSNIFormat = &protocol.FatalError{Err: errors.New("invalid server name format")} //nolint:goerr113 + errInvalidCIDFormat = &protocol.FatalError{Err: errors.New("invalid connection ID format")} //nolint:goerr113 + errLengthMismatch = &protocol.InternalError{Err: errors.New("data length and declared length do not match")} //nolint:goerr113 + errMasterKeyIdentifierTooLarge = &protocol.FatalError{Err: errors.New("master key identifier is over 255 bytes")} //nolint:goerr113 +) diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/extension.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/extension/extension.go similarity index 88% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/extension/extension.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/extension/extension.go index 5173a5863e..e4df859f89 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/extension.go +++ b/vendor/github.com/pion/dtls/v3/pkg/protocol/extension/extension.go @@ -20,6 +20,7 @@ const ( UseSRTPTypeValue TypeValue = 14 ALPNTypeValue TypeValue = 16 UseExtendedMasterSecretTypeValue TypeValue = 23 + ConnectionIDTypeValue TypeValue = 54 RenegotiationInfoTypeValue TypeValue = 65281 ) @@ -64,6 +65,10 @@ func Unmarshal(buf []byte) ([]Extension, error) { err = unmarshalAndAppend(buf[offset:], &ServerName{}) case SupportedEllipticCurvesTypeValue: err = unmarshalAndAppend(buf[offset:], &SupportedEllipticCurves{}) + case SupportedPointFormatsTypeValue: + err = unmarshalAndAppend(buf[offset:], &SupportedPointFormats{}) + case SupportedSignatureAlgorithmsTypeValue: + err = unmarshalAndAppend(buf[offset:], &SupportedSignatureAlgorithms{}) case UseSRTPTypeValue: err = unmarshalAndAppend(buf[offset:], &UseSRTP{}) case ALPNTypeValue: @@ -72,6 +77,8 @@ func Unmarshal(buf []byte) ([]Extension, error) { err = unmarshalAndAppend(buf[offset:], &UseExtendedMasterSecret{}) case RenegotiationInfoTypeValue: err = unmarshalAndAppend(buf[offset:], &RenegotiationInfo{}) + case ConnectionIDTypeValue: + err = unmarshalAndAppend(buf[offset:], &ConnectionID{}) default: } if err != nil { diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/renegotiation_info.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/extension/renegotiation_info.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/extension/renegotiation_info.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/extension/renegotiation_info.go diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/server_name.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/extension/server_name.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/extension/server_name.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/extension/server_name.go diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/srtp_protection_profile.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/extension/srtp_protection_profile.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/extension/srtp_protection_profile.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/extension/srtp_protection_profile.go diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_elliptic_curves.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/extension/supported_elliptic_curves.go similarity index 97% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_elliptic_curves.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/extension/supported_elliptic_curves.go index dd9b54f0d0..e83b5ccb83 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_elliptic_curves.go +++ b/vendor/github.com/pion/dtls/v3/pkg/protocol/extension/supported_elliptic_curves.go @@ -6,7 +6,7 @@ package extension import ( "encoding/binary" - "github.com/pion/dtls/v2/pkg/crypto/elliptic" + "github.com/pion/dtls/v3/pkg/crypto/elliptic" ) const ( diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_point_formats.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/extension/supported_point_formats.go similarity index 85% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_point_formats.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/extension/supported_point_formats.go index 9c2543e6e2..ec877aff2e 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_point_formats.go +++ b/vendor/github.com/pion/dtls/v3/pkg/protocol/extension/supported_point_formats.go @@ -6,7 +6,7 @@ package extension import ( "encoding/binary" - "github.com/pion/dtls/v2/pkg/crypto/elliptic" + "github.com/pion/dtls/v3/pkg/crypto/elliptic" ) const ( @@ -44,12 +44,14 @@ func (s *SupportedPointFormats) Marshal() ([]byte, error) { func (s *SupportedPointFormats) Unmarshal(data []byte) error { if len(data) <= supportedPointFormatsSize { return errBufferTooSmall - } else if TypeValue(binary.BigEndian.Uint16(data)) != s.TypeValue() { + } + + if TypeValue(binary.BigEndian.Uint16(data)) != s.TypeValue() { return errInvalidExtensionType } - pointFormatCount := int(binary.BigEndian.Uint16(data[4:])) - if supportedGroupsHeaderSize+(pointFormatCount) > len(data) { + pointFormatCount := int(data[4]) + if supportedPointFormatsSize+pointFormatCount > len(data) { return errLengthMismatch } diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_signature_algorithms.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/extension/supported_signature_algorithms.go similarity index 94% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_signature_algorithms.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/extension/supported_signature_algorithms.go index 2ff4b90b62..396b9ae383 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_signature_algorithms.go +++ b/vendor/github.com/pion/dtls/v3/pkg/protocol/extension/supported_signature_algorithms.go @@ -6,9 +6,9 @@ package extension import ( "encoding/binary" - "github.com/pion/dtls/v2/pkg/crypto/hash" - "github.com/pion/dtls/v2/pkg/crypto/signature" - "github.com/pion/dtls/v2/pkg/crypto/signaturehash" + "github.com/pion/dtls/v3/pkg/crypto/hash" + "github.com/pion/dtls/v3/pkg/crypto/signature" + "github.com/pion/dtls/v3/pkg/crypto/signaturehash" ) const ( diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/use_master_secret.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/extension/use_master_secret.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/extension/use_master_secret.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/extension/use_master_secret.go diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/use_srtp.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/extension/use_srtp.go similarity index 67% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/extension/use_srtp.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/extension/use_srtp.go index ea9f10872f..6d5f54b23c 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/use_srtp.go +++ b/vendor/github.com/pion/dtls/v3/pkg/protocol/extension/use_srtp.go @@ -3,7 +3,9 @@ package extension -import "encoding/binary" +import ( + "encoding/binary" +) const ( useSRTPHeaderSize = 6 @@ -14,7 +16,8 @@ const ( // // https://tools.ietf.org/html/rfc8422 type UseSRTP struct { - ProtectionProfiles []SRTPProtectionProfile + ProtectionProfiles []SRTPProtectionProfile + MasterKeyIdentifier []byte } // TypeValue returns the extension TypeValue @@ -27,15 +30,20 @@ func (u *UseSRTP) Marshal() ([]byte, error) { out := make([]byte, useSRTPHeaderSize) binary.BigEndian.PutUint16(out, uint16(u.TypeValue())) - binary.BigEndian.PutUint16(out[2:], uint16(2+(len(u.ProtectionProfiles)*2)+ /* MKI Length */ 1)) + binary.BigEndian.PutUint16(out[2:], uint16(2+(len(u.ProtectionProfiles)*2)+ /* MKI Length */ 1+len(u.MasterKeyIdentifier))) binary.BigEndian.PutUint16(out[4:], uint16(len(u.ProtectionProfiles)*2)) for _, v := range u.ProtectionProfiles { out = append(out, []byte{0x00, 0x00}...) binary.BigEndian.PutUint16(out[len(out)-2:], uint16(v)) } + if len(u.MasterKeyIdentifier) > 255 { + return nil, errMasterKeyIdentifierTooLarge + } + + out = append(out, byte(len(u.MasterKeyIdentifier))) + out = append(out, u.MasterKeyIdentifier...) - out = append(out, 0x00) /* MKI Length */ return out, nil } @@ -48,7 +56,8 @@ func (u *UseSRTP) Unmarshal(data []byte) error { } profileCount := int(binary.BigEndian.Uint16(data[4:]) / 2) - if supportedGroupsHeaderSize+(profileCount*2) > len(data) { + masterKeyIdentifierIndex := supportedGroupsHeaderSize + (profileCount * 2) + if masterKeyIdentifierIndex+1 > len(data) { return errLengthMismatch } @@ -58,5 +67,13 @@ func (u *UseSRTP) Unmarshal(data []byte) error { u.ProtectionProfiles = append(u.ProtectionProfiles, supportedProfile) } } + + masterKeyIdentifierLen := int(data[masterKeyIdentifierIndex]) + if masterKeyIdentifierIndex+masterKeyIdentifierLen >= len(data) { + return errLengthMismatch + } + + u.MasterKeyIdentifier = append([]byte{}, data[masterKeyIdentifierIndex+1:masterKeyIdentifierIndex+1+masterKeyIdentifierLen]...) + return nil } diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/cipher_suite.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/cipher_suite.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/cipher_suite.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/cipher_suite.go diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/errors.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/errors.go similarity index 98% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/errors.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/errors.go index 1354300c41..4f007198fe 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/errors.go +++ b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/errors.go @@ -6,7 +6,7 @@ package handshake import ( "errors" - "github.com/pion/dtls/v2/pkg/protocol" + "github.com/pion/dtls/v3/pkg/protocol" ) // Typed errors diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/handshake.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/handshake.go similarity index 96% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/handshake.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/handshake.go index b1f682bf5f..6f0eb9c711 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/handshake.go +++ b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/handshake.go @@ -5,9 +5,9 @@ package handshake import ( - "github.com/pion/dtls/v2/internal/ciphersuite/types" - "github.com/pion/dtls/v2/internal/util" - "github.com/pion/dtls/v2/pkg/protocol" + "github.com/pion/dtls/v3/internal/ciphersuite/types" + "github.com/pion/dtls/v3/internal/util" + "github.com/pion/dtls/v3/pkg/protocol" ) // Type is the unique identifier for each handshake message diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/header.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/header.go similarity index 97% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/header.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/header.go index 4f9a96287e..619fd2bdba 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/header.go +++ b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/header.go @@ -6,7 +6,7 @@ package handshake import ( "encoding/binary" - "github.com/pion/dtls/v2/internal/util" + "github.com/pion/dtls/v3/internal/util" ) // HeaderLength msg_len for Handshake messages assumes an extra diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_certificate.go similarity index 97% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_certificate.go index d5c861d90e..54b0bfddba 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate.go +++ b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_certificate.go @@ -4,7 +4,7 @@ package handshake import ( - "github.com/pion/dtls/v2/internal/util" + "github.com/pion/dtls/v3/internal/util" ) // MessageCertificate is a DTLS Handshake Message diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate_request.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_certificate_request.go similarity index 95% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate_request.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_certificate_request.go index 11a44d440c..5c3ac63c58 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate_request.go +++ b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_certificate_request.go @@ -6,10 +6,10 @@ package handshake import ( "encoding/binary" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" - "github.com/pion/dtls/v2/pkg/crypto/hash" - "github.com/pion/dtls/v2/pkg/crypto/signature" - "github.com/pion/dtls/v2/pkg/crypto/signaturehash" + "github.com/pion/dtls/v3/pkg/crypto/clientcertificate" + "github.com/pion/dtls/v3/pkg/crypto/hash" + "github.com/pion/dtls/v3/pkg/crypto/signature" + "github.com/pion/dtls/v3/pkg/crypto/signaturehash" ) /* diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate_verify.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_certificate_verify.go similarity index 94% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate_verify.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_certificate_verify.go index 9e02a9c11a..9d09b31ca9 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate_verify.go +++ b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_certificate_verify.go @@ -6,8 +6,8 @@ package handshake import ( "encoding/binary" - "github.com/pion/dtls/v2/pkg/crypto/hash" - "github.com/pion/dtls/v2/pkg/crypto/signature" + "github.com/pion/dtls/v3/pkg/crypto/hash" + "github.com/pion/dtls/v3/pkg/crypto/signature" ) // MessageCertificateVerify provide explicit verification of a diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_client_hello.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_client_hello.go similarity index 97% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_client_hello.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_client_hello.go index bea6dd9695..c651718e51 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_client_hello.go +++ b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_client_hello.go @@ -6,8 +6,8 @@ package handshake import ( "encoding/binary" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/extension" + "github.com/pion/dtls/v3/pkg/protocol" + "github.com/pion/dtls/v3/pkg/protocol/extension" ) /* diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_client_key_exchange.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_client_key_exchange.go similarity index 97% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_client_key_exchange.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_client_key_exchange.go index 2abcd5bf7b..626361c6c9 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_client_key_exchange.go +++ b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_client_key_exchange.go @@ -6,7 +6,7 @@ package handshake import ( "encoding/binary" - "github.com/pion/dtls/v2/internal/ciphersuite/types" + "github.com/pion/dtls/v3/internal/ciphersuite/types" ) // MessageClientKeyExchange is a DTLS Handshake Message diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_finished.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_finished.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_finished.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_finished.go diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_hello_verify_request.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_hello_verify_request.go similarity index 97% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_hello_verify_request.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_hello_verify_request.go index 398e59cc36..98960400c2 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_hello_verify_request.go +++ b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_hello_verify_request.go @@ -4,7 +4,7 @@ package handshake import ( - "github.com/pion/dtls/v2/pkg/protocol" + "github.com/pion/dtls/v3/pkg/protocol" ) // MessageHelloVerifyRequest is as follows: diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_hello.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_server_hello.go similarity index 96% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_hello.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_server_hello.go index caf186da8e..a1e86e1b24 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_hello.go +++ b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_server_hello.go @@ -6,8 +6,8 @@ package handshake import ( "encoding/binary" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/extension" + "github.com/pion/dtls/v3/pkg/protocol" + "github.com/pion/dtls/v3/pkg/protocol/extension" ) // MessageServerHello is sent in response to a ClientHello diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_hello_done.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_server_hello_done.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_hello_done.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_server_hello_done.go diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_key_exchange.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_server_key_exchange.go similarity index 95% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_key_exchange.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_server_key_exchange.go index 82abbe0d48..1edac45f9c 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_key_exchange.go +++ b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/message_server_key_exchange.go @@ -6,10 +6,10 @@ package handshake import ( "encoding/binary" - "github.com/pion/dtls/v2/internal/ciphersuite/types" - "github.com/pion/dtls/v2/pkg/crypto/elliptic" - "github.com/pion/dtls/v2/pkg/crypto/hash" - "github.com/pion/dtls/v2/pkg/crypto/signature" + "github.com/pion/dtls/v3/internal/ciphersuite/types" + "github.com/pion/dtls/v3/pkg/crypto/elliptic" + "github.com/pion/dtls/v3/pkg/crypto/hash" + "github.com/pion/dtls/v3/pkg/crypto/signature" ) // MessageServerKeyExchange supports ECDH and PSK diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/random.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/random.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/random.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/handshake/random.go diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/errors.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/recordlayer/errors.go similarity index 96% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/errors.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/recordlayer/errors.go index 1c18988443..ba2b396b80 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/errors.go +++ b/vendor/github.com/pion/dtls/v3/pkg/protocol/recordlayer/errors.go @@ -7,7 +7,7 @@ package recordlayer import ( "errors" - "github.com/pion/dtls/v2/pkg/protocol" + "github.com/pion/dtls/v3/pkg/protocol" ) var ( diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/header.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/recordlayer/header.go similarity index 62% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/header.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/recordlayer/header.go index 92252502b1..0899d5a22c 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/header.go +++ b/vendor/github.com/pion/dtls/v3/pkg/protocol/recordlayer/header.go @@ -6,8 +6,8 @@ package recordlayer import ( "encoding/binary" - "github.com/pion/dtls/v2/internal/util" - "github.com/pion/dtls/v2/pkg/protocol" + "github.com/pion/dtls/v3/internal/util" + "github.com/pion/dtls/v3/pkg/protocol" ) // Header implements a TLS RecordLayer header @@ -17,11 +17,16 @@ type Header struct { Version protocol.Version Epoch uint16 SequenceNumber uint64 // uint48 in spec + + // Optional Fields + ConnectionID []byte } // RecordLayer enums const ( - HeaderSize = 13 + // FixedHeaderSize is the size of a DTLS record header when connection IDs + // are not in use. + FixedHeaderSize = 13 MaxSequenceNumber = 0x0000FFFFFFFFFFFF ) @@ -31,22 +36,33 @@ func (h *Header) Marshal() ([]byte, error) { return nil, errSequenceNumberOverflow } - out := make([]byte, HeaderSize) + hs := FixedHeaderSize + len(h.ConnectionID) + + out := make([]byte, hs) out[0] = byte(h.ContentType) out[1] = h.Version.Major out[2] = h.Version.Minor binary.BigEndian.PutUint16(out[3:], h.Epoch) util.PutBigEndianUint48(out[5:], h.SequenceNumber) - binary.BigEndian.PutUint16(out[HeaderSize-2:], h.ContentLen) + copy(out[11:11+len(h.ConnectionID)], h.ConnectionID) + binary.BigEndian.PutUint16(out[hs-2:], h.ContentLen) return out, nil } // Unmarshal populates a TLS RecordLayer Header from binary func (h *Header) Unmarshal(data []byte) error { - if len(data) < HeaderSize { + if len(data) < FixedHeaderSize { return errBufferTooSmall } h.ContentType = protocol.ContentType(data[0]) + if h.ContentType == protocol.ContentTypeConnectionID { + // If a CID was expected the ConnectionID should have been initialized. + if len(data) < FixedHeaderSize+len(h.ConnectionID) { + return errBufferTooSmall + } + h.ConnectionID = data[11 : 11+len(h.ConnectionID)] + } + h.Version.Major = data[1] h.Version.Minor = data[2] h.Epoch = binary.BigEndian.Uint16(data[3:]) @@ -62,3 +78,8 @@ func (h *Header) Unmarshal(data []byte) error { return nil } + +// Size returns the total size of the header. +func (h *Header) Size() int { + return FixedHeaderSize + len(h.ConnectionID) +} diff --git a/vendor/github.com/pion/dtls/v3/pkg/protocol/recordlayer/inner_plaintext.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/recordlayer/inner_plaintext.go new file mode 100644 index 0000000000..296475a6cc --- /dev/null +++ b/vendor/github.com/pion/dtls/v3/pkg/protocol/recordlayer/inner_plaintext.go @@ -0,0 +1,47 @@ +// SPDX-FileCopyrightText: 2023 The Pion community +// SPDX-License-Identifier: MIT + +package recordlayer + +import ( + "github.com/pion/dtls/v3/pkg/protocol" + "golang.org/x/crypto/cryptobyte" +) + +// InnerPlaintext implements DTLSInnerPlaintext +// +// https://datatracker.ietf.org/doc/html/rfc9146#name-record-layer-extensions +type InnerPlaintext struct { + Content []byte + RealType protocol.ContentType + Zeros uint +} + +// Marshal encodes a DTLS InnerPlaintext to binary +func (p *InnerPlaintext) Marshal() ([]byte, error) { + var out cryptobyte.Builder + out.AddBytes(p.Content) + out.AddUint8(uint8(p.RealType)) + out.AddBytes(make([]byte, p.Zeros)) + return out.Bytes() +} + +// Unmarshal populates a DTLS InnerPlaintext from binary +func (p *InnerPlaintext) Unmarshal(data []byte) error { + // Process in reverse + i := len(data) - 1 + for i >= 0 { + if data[i] != 0 { + p.Zeros = uint(len(data) - 1 - i) + break + } + i-- + } + if i == 0 { + return errBufferTooSmall + } + p.RealType = protocol.ContentType(data[i]) + p.Content = append([]byte{}, data[:i]...) + + return nil +} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/recordlayer.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/recordlayer/recordlayer.go similarity index 59% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/recordlayer.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/recordlayer/recordlayer.go index a570f745f1..61e25a5638 100644 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/recordlayer.go +++ b/vendor/github.com/pion/dtls/v3/pkg/protocol/recordlayer/recordlayer.go @@ -6,11 +6,28 @@ package recordlayer import ( "encoding/binary" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/alert" - "github.com/pion/dtls/v2/pkg/protocol/handshake" + "github.com/pion/dtls/v3/pkg/protocol" + "github.com/pion/dtls/v3/pkg/protocol/alert" + "github.com/pion/dtls/v3/pkg/protocol/handshake" ) +// DTLS fixed size record layer header when Connection IDs are not in-use. + +// --------------------------------- +// | Type | Version | Epoch | +// --------------------------------- +// | Epoch | Sequence Number | +// --------------------------------- +// | Sequence Number | Length | +// --------------------------------- +// | Length | Fragment... | +// --------------------------------- + +// fixedHeaderLenIdx is the index at which the record layer content length is +// specified in a fixed length header (i.e. one that does not include a +// Connection ID). +const fixedHeaderLenIdx = 11 + // RecordLayer which handles all data transport. // The record layer is assumed to sit directly on top of some // reliable transport such as TCP. The record layer can carry four types of content: @@ -51,14 +68,11 @@ func (r *RecordLayer) Marshal() ([]byte, error) { // Unmarshal populates the RecordLayer from binary func (r *RecordLayer) Unmarshal(data []byte) error { - if len(data) < HeaderSize { - return errBufferTooSmall - } if err := r.Header.Unmarshal(data); err != nil { return err } - switch protocol.ContentType(data[0]) { + switch r.Header.ContentType { case protocol.ContentTypeChangeCipherSpec: r.Content = &protocol.ChangeCipherSpec{} case protocol.ContentTypeAlert: @@ -71,7 +85,7 @@ func (r *RecordLayer) Unmarshal(data []byte) error { return errInvalidContentType } - return r.Content.Unmarshal(data[HeaderSize:]) + return r.Content.Unmarshal(data[r.Header.Size()+len(r.Header.ConnectionID):]) } // UnpackDatagram extracts all RecordLayer messages from a single datagram. @@ -85,11 +99,40 @@ func UnpackDatagram(buf []byte) ([][]byte, error) { out := [][]byte{} for offset := 0; len(buf) != offset; { - if len(buf)-offset <= HeaderSize { + if len(buf)-offset <= FixedHeaderSize { + return nil, ErrInvalidPacketLength + } + + pktLen := (FixedHeaderSize + int(binary.BigEndian.Uint16(buf[offset+11:]))) + if offset+pktLen > len(buf) { + return nil, ErrInvalidPacketLength + } + + out = append(out, buf[offset:offset+pktLen]) + offset += pktLen + } + + return out, nil +} + +// ContentAwareUnpackDatagram is the same as UnpackDatagram but considers the +// presence of a connection identifier if the record is of content type +// tls12_cid. +func ContentAwareUnpackDatagram(buf []byte, cidLength int) ([][]byte, error) { + out := [][]byte{} + + for offset := 0; len(buf) != offset; { + headerSize := FixedHeaderSize + lenIdx := fixedHeaderLenIdx + if protocol.ContentType(buf[offset]) == protocol.ContentTypeConnectionID { + headerSize += cidLength + lenIdx += cidLength + } + if len(buf)-offset <= headerSize { return nil, ErrInvalidPacketLength } - pktLen := (HeaderSize + int(binary.BigEndian.Uint16(buf[offset+11:]))) + pktLen := (headerSize + int(binary.BigEndian.Uint16(buf[offset+lenIdx:]))) if offset+pktLen > len(buf) { return nil, ErrInvalidPacketLength } diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/version.go b/vendor/github.com/pion/dtls/v3/pkg/protocol/version.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/pkg/protocol/version.go rename to vendor/github.com/pion/dtls/v3/pkg/protocol/version.go diff --git a/vendor/github.com/pion/dtls/v2/renovate.json b/vendor/github.com/pion/dtls/v3/renovate.json similarity index 100% rename from vendor/github.com/pion/dtls/v2/renovate.json rename to vendor/github.com/pion/dtls/v3/renovate.json diff --git a/vendor/github.com/pion/dtls/v3/resume.go b/vendor/github.com/pion/dtls/v3/resume.go new file mode 100644 index 0000000000..0b76314a5f --- /dev/null +++ b/vendor/github.com/pion/dtls/v3/resume.go @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: 2023 The Pion community +// SPDX-License-Identifier: MIT + +package dtls + +import ( + "net" +) + +// Resume imports an already established dtls connection using a specific dtls state +func Resume(state *State, conn net.PacketConn, rAddr net.Addr, config *Config) (*Conn, error) { + if err := state.initCipherSuite(); err != nil { + return nil, err + } + return createConn(conn, rAddr, config, state.isClient, state) +} diff --git a/vendor/github.com/pion/dtls/v2/session.go b/vendor/github.com/pion/dtls/v3/session.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/session.go rename to vendor/github.com/pion/dtls/v3/session.go diff --git a/vendor/github.com/pion/dtls/v2/srtp_protection_profile.go b/vendor/github.com/pion/dtls/v3/srtp_protection_profile.go similarity index 95% rename from vendor/github.com/pion/dtls/v2/srtp_protection_profile.go rename to vendor/github.com/pion/dtls/v3/srtp_protection_profile.go index 8b7e471f3d..bc242095ba 100644 --- a/vendor/github.com/pion/dtls/v2/srtp_protection_profile.go +++ b/vendor/github.com/pion/dtls/v3/srtp_protection_profile.go @@ -3,7 +3,7 @@ package dtls -import "github.com/pion/dtls/v2/pkg/protocol/extension" +import "github.com/pion/dtls/v3/pkg/protocol/extension" // SRTPProtectionProfile defines the parameters and options that are in effect for the SRTP processing // https://tools.ietf.org/html/rfc5764#section-4.1.2 diff --git a/vendor/github.com/pion/dtls/v2/state.go b/vendor/github.com/pion/dtls/v3/state.go similarity index 68% rename from vendor/github.com/pion/dtls/v2/state.go rename to vendor/github.com/pion/dtls/v3/state.go index 9f26d43f13..f1afb857d4 100644 --- a/vendor/github.com/pion/dtls/v2/state.go +++ b/vendor/github.com/pion/dtls/v3/state.go @@ -6,12 +6,14 @@ package dtls import ( "bytes" "encoding/gob" + "errors" "sync/atomic" - "github.com/pion/dtls/v2/pkg/crypto/elliptic" - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/protocol/handshake" - "github.com/pion/transport/v2/replaydetector" + "github.com/pion/dtls/v3/pkg/crypto/elliptic" + "github.com/pion/dtls/v3/pkg/crypto/prf" + "github.com/pion/dtls/v3/pkg/crypto/signaturehash" + "github.com/pion/dtls/v3/pkg/protocol/handshake" + "github.com/pion/transport/v3/replaydetector" ) // State holds the dtls connection state and implements both encoding.BinaryMarshaler and encoding.BinaryUnmarshaler @@ -21,11 +23,28 @@ type State struct { localRandom, remoteRandom handshake.Random masterSecret []byte cipherSuite CipherSuite // nil if a cipherSuite hasn't been chosen + CipherSuiteID CipherSuiteID - srtpProtectionProfile atomic.Value // Negotiated SRTPProtectionProfile - PeerCertificates [][]byte - IdentityHint []byte - SessionID []byte + srtpProtectionProfile atomic.Value // Negotiated SRTPProtectionProfile + remoteSRTPMasterKeyIdentifier []byte + + PeerCertificates [][]byte + IdentityHint []byte + SessionID []byte + + // Connection Identifiers must be negotiated afresh on session resumption. + // https://datatracker.ietf.org/doc/html/rfc9146#name-the-connection_id-extension + + // localConnectionID is the locally generated connection ID that is expected + // to be received from the remote endpoint. + // For a server, this is the connection ID sent in ServerHello. + // For a client, this is the connection ID sent in the ClientHello. + localConnectionID atomic.Value + // remoteConnectionID is the connection ID that the remote endpoint + // specifies should be sent. + // For a server, this is the connection ID received in the ClientHello. + // For a client, this is the connection ID received in the ServerHello. + remoteConnectionID []byte isClient bool @@ -38,6 +57,7 @@ type State struct { handshakeSendSequence int handshakeRecvSequence int serverName string + remoteCertRequestAlgs []signaturehash.Algorithm remoteRequestedCertificate bool // Did we get a CertificateRequest localCertificatesVerify []byte // cache CertificateVerify localVerifyData []byte // cached VerifyData @@ -62,18 +82,31 @@ type serializedState struct { PeerCertificates [][]byte IdentityHint []byte SessionID []byte + LocalConnectionID []byte + RemoteConnectionID []byte IsClient bool + NegotiatedProtocol string } -func (s *State) clone() *State { - serialized := s.serialize() +var errCipherSuiteNotSet = &InternalError{Err: errors.New("cipher suite not set")} //nolint:goerr113 + +func (s *State) clone() (*State, error) { + serialized, err := s.serialize() + if err != nil { + return nil, err + } state := &State{} state.deserialize(*serialized) - return state + return state, err } -func (s *State) serialize() *serializedState { +func (s *State) serialize() (*serializedState, error) { + if s.cipherSuite == nil { + return nil, errCipherSuiteNotSet + } + cipherSuiteID := uint16(s.cipherSuite.ID()) + // Marshal random values localRnd := s.localRandom.MarshalFixed() remoteRnd := s.remoteRandom.MarshalFixed() @@ -82,7 +115,7 @@ func (s *State) serialize() *serializedState { return &serializedState{ LocalEpoch: s.getLocalEpoch(), RemoteEpoch: s.getRemoteEpoch(), - CipherSuiteID: uint16(s.cipherSuite.ID()), + CipherSuiteID: cipherSuiteID, MasterSecret: s.masterSecret, SequenceNumber: atomic.LoadUint64(&s.localSequenceNumber[epoch]), LocalRandom: localRnd, @@ -91,8 +124,11 @@ func (s *State) serialize() *serializedState { PeerCertificates: s.PeerCertificates, IdentityHint: s.IdentityHint, SessionID: s.SessionID, + LocalConnectionID: s.getLocalConnectionID(), + RemoteConnectionID: s.remoteConnectionID, IsClient: s.isClient, - } + NegotiatedProtocol: s.NegotiatedProtocol, + }, nil } func (s *State) deserialize(serialized serializedState) { @@ -120,15 +156,24 @@ func (s *State) deserialize(serialized serializedState) { s.masterSecret = serialized.MasterSecret // Set cipher suite - s.cipherSuite = cipherSuiteForID(CipherSuiteID(serialized.CipherSuiteID), nil) + s.CipherSuiteID = CipherSuiteID(serialized.CipherSuiteID) + s.cipherSuite = cipherSuiteForID(s.CipherSuiteID, nil) atomic.StoreUint64(&s.localSequenceNumber[epoch], serialized.SequenceNumber) s.setSRTPProtectionProfile(SRTPProtectionProfile(serialized.SRTPProtectionProfile)) // Set remote certificate s.PeerCertificates = serialized.PeerCertificates + s.IdentityHint = serialized.IdentityHint + + // Set local and remote connection IDs + s.setLocalConnectionID(serialized.LocalConnectionID) + s.remoteConnectionID = serialized.RemoteConnectionID + s.SessionID = serialized.SessionID + + s.NegotiatedProtocol = serialized.NegotiatedProtocol } func (s *State) initCipherSuite() error { @@ -153,7 +198,10 @@ func (s *State) initCipherSuite() error { // MarshalBinary is a binary.BinaryMarshaler.MarshalBinary implementation func (s *State) MarshalBinary() ([]byte, error) { - serialized := s.serialize() + serialized, err := s.serialize() + if err != nil { + return nil, err + } var buf bytes.Buffer enc := gob.NewEncoder(&buf) @@ -226,3 +274,20 @@ func (s *State) getSRTPProtectionProfile() SRTPProtectionProfile { return 0 } + +func (s *State) getLocalConnectionID() []byte { + if val, ok := s.localConnectionID.Load().([]byte); ok { + return val + } + + return nil +} + +func (s *State) setLocalConnectionID(v []byte) { + s.localConnectionID.Store(v) +} + +// RemoteRandomBytes returns the remote client hello random bytes +func (s *State) RemoteRandomBytes() [handshake.RandomBytesLength]byte { + return s.remoteRandom.RandomBytes +} diff --git a/vendor/github.com/pion/dtls/v2/util.go b/vendor/github.com/pion/dtls/v3/util.go similarity index 100% rename from vendor/github.com/pion/dtls/v2/util.go rename to vendor/github.com/pion/dtls/v3/util.go diff --git a/vendor/github.com/pion/ice/v2/AUTHORS.txt b/vendor/github.com/pion/ice/v2/AUTHORS.txt deleted file mode 100644 index 56269cc728..0000000000 --- a/vendor/github.com/pion/ice/v2/AUTHORS.txt +++ /dev/null @@ -1,68 +0,0 @@ -# Thank you to everyone that made Pion possible. If you are interested in contributing -# we would love to have you https://github.com/pion/webrtc/wiki/Contributing -# -# This file is auto generated, using git to list all individuals contributors. -# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting -Aaron France -Adam Kiss -adwpc -Aleksandr Razumov -aler9 <46489434+aler9@users.noreply.github.com> -Anshul -Antoine Baché -ar-hosseinkhani -Artur Shellunts -Assad Obaid -Atsushi Watanabe -backkem -boks1971 -buptczq -cgojin -Chao Yuan -cnderrauber -David Hamilton -David Zhao -David Zhao -Eric Daniels -Genteure -Henry -hexiang -hn8 <10730886+hn8@users.noreply.github.com> -Hugo Arregui -Hugo Arregui -Jason Maldonis -Jerko Steiner -JooYoung -Juliusz Chroboczek -Kacper Bąk <56700396+53jk1@users.noreply.github.com> -Kevin Caffrey -Konstantin Itskov -korymiller1489 -Kyle Carberry -Lander Noterman -Luke Curley -Meelap Shah -Michael MacDonald -Michael MacDonald -Mikhail Bragin -Miroslav Šedivý -Nevio Vesic -Ori Bernstein -Rasmus Hanning -Robert Eperjesi -Sam Lancia -Sam Lancia -San9H0 -Sean DuBois -Sean DuBois -Sebastian Waisbrot -Sidney San Martín -Steffen Vogel -Will Forcey -Woodrow Douglass -Yutaka Takeda -ZHENK -Zizheng Tai - -# List of contributors not appearing in Git history - diff --git a/vendor/github.com/pion/ice/v2/addr.go b/vendor/github.com/pion/ice/v2/addr.go deleted file mode 100644 index 1d70025be7..0000000000 --- a/vendor/github.com/pion/ice/v2/addr.go +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "net" -) - -func parseMulticastAnswerAddr(in net.Addr) (net.IP, bool) { - switch addr := in.(type) { - case *net.IPAddr: - return addr.IP, true - case *net.UDPAddr: - return addr.IP, true - case *net.TCPAddr: - return addr.IP, true - } - return nil, false -} - -func parseAddr(in net.Addr) (net.IP, int, NetworkType, bool) { - switch addr := in.(type) { - case *net.UDPAddr: - return addr.IP, addr.Port, NetworkTypeUDP4, true - case *net.TCPAddr: - return addr.IP, addr.Port, NetworkTypeTCP4, true - } - return nil, 0, 0, false -} - -func createAddr(network NetworkType, ip net.IP, port int) net.Addr { - switch { - case network.IsTCP(): - return &net.TCPAddr{IP: ip, Port: port} - default: - return &net.UDPAddr{IP: ip, Port: port} - } -} - -func addrEqual(a, b net.Addr) bool { - aIP, aPort, aType, aOk := parseAddr(a) - if !aOk { - return false - } - - bIP, bPort, bType, bOk := parseAddr(b) - if !bOk { - return false - } - - return aType == bType && aIP.Equal(bIP) && aPort == bPort -} - -// AddrPort is an IP and a port number. -type AddrPort [18]byte - -func toAddrPort(addr net.Addr) AddrPort { - var ap AddrPort - switch addr := addr.(type) { - case *net.UDPAddr: - copy(ap[:16], addr.IP.To16()) - ap[16] = uint8(addr.Port >> 8) - ap[17] = uint8(addr.Port) - case *net.TCPAddr: - copy(ap[:16], addr.IP.To16()) - ap[16] = uint8(addr.Port >> 8) - ap[17] = uint8(addr.Port) - } - return ap -} diff --git a/vendor/github.com/pion/ice/v2/context.go b/vendor/github.com/pion/ice/v2/context.go deleted file mode 100644 index 36454450c5..0000000000 --- a/vendor/github.com/pion/ice/v2/context.go +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "context" - "time" -) - -func (a *Agent) context() context.Context { - return agentContext(a.done) -} - -type agentContext chan struct{} - -// Done implements context.Context -func (a agentContext) Done() <-chan struct{} { - return (chan struct{})(a) -} - -// Err implements context.Context -func (a agentContext) Err() error { - select { - case <-(chan struct{})(a): - return ErrRunCanceled - default: - return nil - } -} - -// Deadline implements context.Context -func (a agentContext) Deadline() (deadline time.Time, ok bool) { - return time.Time{}, false -} - -// Value implements context.Context -func (a agentContext) Value(interface{}) interface{} { - return nil -} diff --git a/vendor/github.com/pion/ice/v2/mdns.go b/vendor/github.com/pion/ice/v2/mdns.go deleted file mode 100644 index aa82316487..0000000000 --- a/vendor/github.com/pion/ice/v2/mdns.go +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "github.com/google/uuid" - "github.com/pion/logging" - "github.com/pion/mdns" - "github.com/pion/transport/v2" - "golang.org/x/net/ipv4" -) - -// MulticastDNSMode represents the different Multicast modes ICE can run in -type MulticastDNSMode byte - -// MulticastDNSMode enum -const ( - // MulticastDNSModeDisabled means remote mDNS candidates will be discarded, and local host candidates will use IPs - MulticastDNSModeDisabled MulticastDNSMode = iota + 1 - - // MulticastDNSModeQueryOnly means remote mDNS candidates will be accepted, and local host candidates will use IPs - MulticastDNSModeQueryOnly - - // MulticastDNSModeQueryAndGather means remote mDNS candidates will be accepted, and local host candidates will use mDNS - MulticastDNSModeQueryAndGather -) - -func generateMulticastDNSName() (string, error) { - // https://tools.ietf.org/id/draft-ietf-rtcweb-mdns-ice-candidates-02.html#gathering - // The unique name MUST consist of a version 4 UUID as defined in [RFC4122], followed by “.local”. - u, err := uuid.NewRandom() - return u.String() + ".local", err -} - -func createMulticastDNS(n transport.Net, mDNSMode MulticastDNSMode, mDNSName string, log logging.LeveledLogger) (*mdns.Conn, MulticastDNSMode, error) { - if mDNSMode == MulticastDNSModeDisabled { - return nil, mDNSMode, nil - } - - addr, mdnsErr := n.ResolveUDPAddr("udp4", mdns.DefaultAddress) - if mdnsErr != nil { - return nil, mDNSMode, mdnsErr - } - - l, mdnsErr := n.ListenUDP("udp4", addr) - if mdnsErr != nil { - // If ICE fails to start MulticastDNS server just warn the user and continue - log.Errorf("Failed to enable mDNS, continuing in mDNS disabled mode: (%s)", mdnsErr) - return nil, MulticastDNSModeDisabled, nil - } - - switch mDNSMode { - case MulticastDNSModeQueryOnly: - conn, err := mdns.Server(ipv4.NewPacketConn(l), &mdns.Config{}) - return conn, mDNSMode, err - case MulticastDNSModeQueryAndGather: - conn, err := mdns.Server(ipv4.NewPacketConn(l), &mdns.Config{ - LocalNames: []string{mDNSName}, - }) - return conn, mDNSMode, err - default: - return nil, mDNSMode, nil - } -} diff --git a/vendor/github.com/pion/ice/v2/test_utils.go b/vendor/github.com/pion/ice/v2/test_utils.go deleted file mode 100644 index 235fda3151..0000000000 --- a/vendor/github.com/pion/ice/v2/test_utils.go +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package ice - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func newHostRemote(t *testing.T) *CandidateHost { - remoteHostConfig := &CandidateHostConfig{ - Network: "udp", - Address: "1.2.3.5", - Port: 12350, - Component: 1, - } - hostRemote, err := NewCandidateHost(remoteHostConfig) - require.NoError(t, err) - return hostRemote -} - -func newPrflxRemote(t *testing.T) *CandidatePeerReflexive { - prflxConfig := &CandidatePeerReflexiveConfig{ - Network: "udp", - Address: "10.10.10.2", - Port: 19217, - Component: 1, - RelAddr: "4.3.2.1", - RelPort: 43211, - } - prflxRemote, err := NewCandidatePeerReflexive(prflxConfig) - require.NoError(t, err) - return prflxRemote -} - -func newSrflxRemote(t *testing.T) *CandidateServerReflexive { - srflxConfig := &CandidateServerReflexiveConfig{ - Network: "udp", - Address: "10.10.10.2", - Port: 19218, - Component: 1, - RelAddr: "4.3.2.1", - RelPort: 43212, - } - srflxRemote, err := NewCandidateServerReflexive(srflxConfig) - require.NoError(t, err) - return srflxRemote -} - -func newRelayRemote(t *testing.T) *CandidateRelay { - relayConfig := &CandidateRelayConfig{ - Network: "udp", - Address: "1.2.3.4", - Port: 12340, - Component: 1, - RelAddr: "4.3.2.1", - RelPort: 43210, - } - relayRemote, err := NewCandidateRelay(relayConfig) - require.NoError(t, err) - return relayRemote -} - -func newHostLocal(t *testing.T) *CandidateHost { - localHostConfig := &CandidateHostConfig{ - Network: "udp", - Address: "192.168.1.1", - Port: 19216, - Component: 1, - } - hostLocal, err := NewCandidateHost(localHostConfig) - require.NoError(t, err) - return hostLocal -} diff --git a/vendor/github.com/pion/ice/v2/.gitignore b/vendor/github.com/pion/ice/v4/.gitignore similarity index 100% rename from vendor/github.com/pion/ice/v2/.gitignore rename to vendor/github.com/pion/ice/v4/.gitignore diff --git a/vendor/github.com/pion/ice/v4/.golangci.yml b/vendor/github.com/pion/ice/v4/.golangci.yml new file mode 100644 index 0000000000..a3235bec28 --- /dev/null +++ b/vendor/github.com/pion/ice/v4/.golangci.yml @@ -0,0 +1,125 @@ +# SPDX-FileCopyrightText: 2023 The Pion community +# SPDX-License-Identifier: MIT + +run: + timeout: 5m + +linters-settings: + govet: + enable: + - shadow + misspell: + locale: US + exhaustive: + default-signifies-exhaustive: true + gomodguard: + blocked: + modules: + - github.com/pkg/errors: + recommendations: + - errors + forbidigo: + forbid: + - ^fmt.Print(f|ln)?$ + - ^log.(Panic|Fatal|Print)(f|ln)?$ + - ^os.Exit$ + - ^panic$ + - ^print(ln)?$ + +linters: + enable: + - asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers + - bidichk # Checks for dangerous unicode character sequences + - bodyclose # checks whether HTTP response body is closed successfully + - contextcheck # check the function whether use a non-inherited context + - decorder # check declaration order and count of types, constants, variables and functions + - dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) + - dupl # Tool for code clone detection + - durationcheck # check for two durations multiplied together + - errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases + - errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and optionally reports occations, where the check for the returned error can be omitted. + - errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. + - errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13. + - exhaustive # check exhaustiveness of enum switch statements + - exportloopref # checks for pointers to enclosing loop variables + - forbidigo # Forbids identifiers + - forcetypeassert # finds forced type assertions + - gci # Gci control golang package import order and make it always deterministic. + - gochecknoglobals # Checks that no globals are present in Go code + - gochecknoinits # Checks that no init functions are present in Go code + - gocognit # Computes and checks the cognitive complexity of functions + - goconst # Finds repeated strings that could be replaced by a constant + - gocritic # The most opinionated Go source code linter + - godox # Tool for detection of FIXME, TODO and other comment keywords + - err113 # Golang linter to check the errors handling expressions + - gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification + - gofumpt # Gofumpt checks whether code was gofumpt-ed. + - goheader # Checks is file header matches to pattern + - goimports # Goimports does everything that gofmt does. Additionally it checks unused imports + - gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. + - gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. + - goprintffuncname # Checks that printf-like functions are named with `f` at the end + - gosec # Inspects source code for security problems + - gosimple # Linter for Go source code that specializes in simplifying a code + - govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string + - grouper # An analyzer to analyze expression groups. + - importas # Enforces consistent import aliases + - ineffassign # Detects when assignments to existing variables are not used + - misspell # Finds commonly misspelled English words in comments + - nilerr # Finds the code that returns nil even if it checks that the error is not nil. + - nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. + - noctx # noctx finds sending http request without context.Context + - predeclared # find code that shadows one of Go's predeclared identifiers + - revive # golint replacement, finds style mistakes + - staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks + - stylecheck # Stylecheck is a replacement for golint + - tagliatelle # Checks the struct tags. + - tenv # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17 + - tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes + - typecheck # Like the front-end of a Go compiler, parses and type-checks Go code + - unconvert # Remove unnecessary type conversions + - unparam # Reports unused function parameters + - unused # Checks Go code for unused constants, variables, functions and types + - wastedassign # wastedassign finds wasted assignment statements + - whitespace # Tool for detection of leading and trailing whitespace + disable: + - depguard # Go linter that checks if package imports are in a list of acceptable packages + - containedctx # containedctx is a linter that detects struct contained context.Context field + - cyclop # checks function and package cyclomatic complexity + - funlen # Tool for detection of long functions + - gocyclo # Computes and checks the cyclomatic complexity of functions + - godot # Check if comments end in a period + - gomnd # An analyzer to detect magic numbers. + - ireturn # Accept Interfaces, Return Concrete Types + - lll # Reports long lines + - maintidx # maintidx measures the maintainability index of each function. + - makezero # Finds slice declarations with non-zero initial length + - nakedret # Finds naked returns in functions greater than a specified function length + - nestif # Reports deeply nested if statements + - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity + - nolintlint # Reports ill-formed or insufficient nolint directives + - paralleltest # paralleltest detects missing usage of t.Parallel() method in your Go test + - prealloc # Finds slice declarations that could potentially be preallocated + - promlinter # Check Prometheus metrics naming via promlint + - rowserrcheck # checks whether Err of rows is checked successfully + - sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed. + - testpackage # linter that makes you use a separate _test package + - thelper # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers + - varnamelen # checks that the length of a variable's name matches its scope + - wrapcheck # Checks that errors returned from external packages are wrapped + - wsl # Whitespace Linter - Forces you to use empty lines! + +issues: + exclude-use-default: false + exclude-dirs-use-default: false + exclude-rules: + # Allow complex tests and examples, better to be self contained + - path: (examples|main\.go|_test\.go) + linters: + - forbidigo + - gocognit + + # Allow forbidden identifiers in CLI commands + - path: cmd + linters: + - forbidigo diff --git a/vendor/github.com/pion/ice/v2/.goreleaser.yml b/vendor/github.com/pion/ice/v4/.goreleaser.yml similarity index 100% rename from vendor/github.com/pion/ice/v2/.goreleaser.yml rename to vendor/github.com/pion/ice/v4/.goreleaser.yml diff --git a/vendor/github.com/pion/ice/v2/LICENSE b/vendor/github.com/pion/ice/v4/LICENSE similarity index 100% rename from vendor/github.com/pion/ice/v2/LICENSE rename to vendor/github.com/pion/ice/v4/LICENSE diff --git a/vendor/github.com/pion/ice/v2/README.md b/vendor/github.com/pion/ice/v4/README.md similarity index 90% rename from vendor/github.com/pion/ice/v2/README.md rename to vendor/github.com/pion/ice/v4/README.md index 111ca70570..14e89ade22 100644 --- a/vendor/github.com/pion/ice/v2/README.md +++ b/vendor/github.com/pion/ice/v4/README.md @@ -9,7 +9,7 @@ Slack Widget
GitHub Workflow Status - Go Reference + Go Reference Coverage Status Go Report Card License: MIT @@ -28,7 +28,7 @@ We are always looking to support **your projects**. Please reach out if you have If you need commercial support or don't want to use public methods you can contact us at [team@pion.ly](mailto:team@pion.ly) ### Contributing -Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible: [AUTHORS.txt](./AUTHORS.txt) +Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible ### License MIT License - see [LICENSE](LICENSE) for full text diff --git a/vendor/github.com/pion/ice/v2/active_tcp.go b/vendor/github.com/pion/ice/v4/active_tcp.go similarity index 83% rename from vendor/github.com/pion/ice/v2/active_tcp.go rename to vendor/github.com/pion/ice/v4/active_tcp.go index 024e6e7acb..a6f8387ec4 100644 --- a/vendor/github.com/pion/ice/v2/active_tcp.go +++ b/vendor/github.com/pion/ice/v4/active_tcp.go @@ -7,11 +7,12 @@ import ( "context" "io" "net" + "net/netip" "sync/atomic" "time" "github.com/pion/logging" - "github.com/pion/transport/v2/packetio" + "github.com/pion/transport/v3/packetio" ) type activeTCPConn struct { @@ -20,7 +21,7 @@ type activeTCPConn struct { closed int32 } -func newActiveTCPConn(ctx context.Context, localAddress, remoteAddress string, log logging.LeveledLogger) (a *activeTCPConn) { +func newActiveTCPConn(ctx context.Context, localAddress string, remoteAddress netip.AddrPort, log logging.LeveledLogger) (a *activeTCPConn) { a = &activeTCPConn{ readBuffer: packetio.NewBuffer(), writeBuffer: packetio.NewBuffer(), @@ -42,12 +43,11 @@ func newActiveTCPConn(ctx context.Context, localAddress, remoteAddress string, l dialer := &net.Dialer{ LocalAddr: laddr, } - conn, err := dialer.DialContext(ctx, "tcp", remoteAddress) + conn, err := dialer.DialContext(ctx, "tcp", remoteAddress.String()) if err != nil { log.Infof("Failed to dial TCP address %s: %v", remoteAddress, err) return } - a.remoteAddr.Store(conn.RemoteAddr()) go func() { @@ -95,8 +95,9 @@ func (a *activeTCPConn) ReadFrom(buff []byte) (n int, srcAddr net.Addr, err erro return 0, nil, io.ErrClosedPipe } - srcAddr = a.RemoteAddr() n, err = a.readBuffer.Read(buff) + // RemoteAddr is assuredly set *after* we can read from the buffer + srcAddr = a.RemoteAddr() return } @@ -123,6 +124,11 @@ func (a *activeTCPConn) LocalAddr() net.Addr { return &net.TCPAddr{} } +// RemoteAddr returns the remote address of the connection which is only +// set once a background goroutine has successfully dialed. That means +// this may return ":0" for the address prior to that happening. If this +// becomes an issue, we can introduce a synchronization point between Dial +// and these methods. func (a *activeTCPConn) RemoteAddr() net.Addr { if v, ok := a.remoteAddr.Load().(*net.TCPAddr); ok { return v diff --git a/vendor/github.com/pion/ice/v4/addr.go b/vendor/github.com/pion/ice/v4/addr.go new file mode 100644 index 0000000000..fb40061d24 --- /dev/null +++ b/vendor/github.com/pion/ice/v4/addr.go @@ -0,0 +1,145 @@ +// SPDX-FileCopyrightText: 2023 The Pion community +// SPDX-License-Identifier: MIT + +package ice + +import ( + "fmt" + "net" + "net/netip" +) + +func addrWithOptionalZone(addr netip.Addr, zone string) netip.Addr { + if zone == "" { + return addr + } + if addr.Is6() && (addr.IsLinkLocalUnicast() || addr.IsLinkLocalMulticast()) { + return addr.WithZone(zone) + } + return addr +} + +// parseAddrFromIface should only be used when it's known the address belongs to that interface. +// e.g. it's LocalAddress on a listener. +func parseAddrFromIface(in net.Addr, ifcName string) (netip.Addr, int, NetworkType, error) { + addr, port, nt, err := parseAddr(in) + if err != nil { + return netip.Addr{}, 0, 0, err + } + if _, ok := in.(*net.IPNet); ok { + // net.IPNet does not have a Zone but we provide it from the interface + addr = addrWithOptionalZone(addr, ifcName) + } + return addr, port, nt, nil +} + +func parseAddr(in net.Addr) (netip.Addr, int, NetworkType, error) { + switch addr := in.(type) { + case *net.IPNet: + ipAddr, err := ipAddrToNetIP(addr.IP, "") + if err != nil { + return netip.Addr{}, 0, 0, err + } + return ipAddr, 0, 0, nil + case *net.IPAddr: + ipAddr, err := ipAddrToNetIP(addr.IP, addr.Zone) + if err != nil { + return netip.Addr{}, 0, 0, err + } + return ipAddr, 0, 0, nil + case *net.UDPAddr: + ipAddr, err := ipAddrToNetIP(addr.IP, addr.Zone) + if err != nil { + return netip.Addr{}, 0, 0, err + } + var nt NetworkType + if ipAddr.Is4() { + nt = NetworkTypeUDP4 + } else { + nt = NetworkTypeUDP6 + } + return ipAddr, addr.Port, nt, nil + case *net.TCPAddr: + ipAddr, err := ipAddrToNetIP(addr.IP, addr.Zone) + if err != nil { + return netip.Addr{}, 0, 0, err + } + var nt NetworkType + if ipAddr.Is4() { + nt = NetworkTypeTCP4 + } else { + nt = NetworkTypeTCP6 + } + return ipAddr, addr.Port, nt, nil + default: + return netip.Addr{}, 0, 0, addrParseError{in} + } +} + +type addrParseError struct { + addr net.Addr +} + +func (e addrParseError) Error() string { + return fmt.Sprintf("do not know how to parse address type %T", e.addr) +} + +type ipConvertError struct { + ip []byte +} + +func (e ipConvertError) Error() string { + return fmt.Sprintf("failed to convert IP '%s' to netip.Addr", e.ip) +} + +func ipAddrToNetIP(ip []byte, zone string) (netip.Addr, error) { + netIPAddr, ok := netip.AddrFromSlice(ip) + if !ok { + return netip.Addr{}, ipConvertError{ip} + } + // we'd rather have an IPv4-mapped IPv6 become IPv4 so that it is usable. + netIPAddr = netIPAddr.Unmap() + netIPAddr = addrWithOptionalZone(netIPAddr, zone) + return netIPAddr, nil +} + +func createAddr(network NetworkType, ip netip.Addr, port int) net.Addr { + switch { + case network.IsTCP(): + return &net.TCPAddr{IP: ip.AsSlice(), Port: port, Zone: ip.Zone()} + default: + return &net.UDPAddr{IP: ip.AsSlice(), Port: port, Zone: ip.Zone()} + } +} + +func addrEqual(a, b net.Addr) bool { + aIP, aPort, aType, aErr := parseAddr(a) + if aErr != nil { + return false + } + + bIP, bPort, bType, bErr := parseAddr(b) + if bErr != nil { + return false + } + + return aType == bType && aIP.Compare(bIP) == 0 && aPort == bPort +} + +// AddrPort is an IP and a port number. +type AddrPort [18]byte + +func toAddrPort(addr net.Addr) AddrPort { + var ap AddrPort + switch addr := addr.(type) { + case *net.UDPAddr: + copy(ap[:16], addr.IP.To16()) + ap[16] = uint8(addr.Port >> 8) + ap[17] = uint8(addr.Port) + case *net.TCPAddr: + copy(ap[:16], addr.IP.To16()) + ap[16] = uint8(addr.Port >> 8) + ap[17] = uint8(addr.Port) + } + return ap +} diff --git a/vendor/github.com/pion/ice/v2/agent.go b/vendor/github.com/pion/ice/v4/agent.go similarity index 84% rename from vendor/github.com/pion/ice/v2/agent.go rename to vendor/github.com/pion/ice/v4/agent.go index c2718fc67d..b9268b8bd0 100644 --- a/vendor/github.com/pion/ice/v2/agent.go +++ b/vendor/github.com/pion/ice/v4/agent.go @@ -7,25 +7,24 @@ package ice import ( "context" - "errors" "fmt" "math" "net" - "strconv" + "net/netip" "strings" "sync" "sync/atomic" "time" - atomicx "github.com/pion/ice/v2/internal/atomic" - stunx "github.com/pion/ice/v2/internal/stun" + stunx "github.com/pion/ice/v4/internal/stun" + "github.com/pion/ice/v4/internal/taskloop" "github.com/pion/logging" - "github.com/pion/mdns" - "github.com/pion/stun" - "github.com/pion/transport/v2" - "github.com/pion/transport/v2/packetio" - "github.com/pion/transport/v2/stdnet" - "github.com/pion/transport/v2/vnet" + "github.com/pion/mdns/v2" + "github.com/pion/stun/v3" + "github.com/pion/transport/v3" + "github.com/pion/transport/v3/packetio" + "github.com/pion/transport/v3/stdnet" + "github.com/pion/transport/v3/vnet" "golang.org/x/net/proxy" ) @@ -38,15 +37,12 @@ type bindingRequest struct { // Agent represents the ICE agent type Agent struct { - chanTask chan task - afterRunFn []func(ctx context.Context) - muAfterRun sync.Mutex + loop *taskloop.Loop onConnectionStateChangeHdlr atomic.Value // func(ConnectionState) onSelectedCandidatePairChangeHdlr atomic.Value // func(Candidate, Candidate) onCandidateHdlr atomic.Value // func(Candidate) - // State owned by the taskLoop onConnected chan struct{} onConnectedOnce sync.Once @@ -74,6 +70,7 @@ type Agent struct { srflxAcceptanceMinWait time.Duration prflxAcceptanceMinWait time.Duration relayAcceptanceMinWait time.Duration + stunGatherTimeout time.Duration tcpPriorityOffset uint16 disableActiveTCP bool @@ -122,11 +119,6 @@ type Agent struct { // 1:1 D-NAT IP address mapping extIPMapper *externalIPMapper - // State for closing - done chan struct{} - taskLoopDone chan struct{} - err atomicx.Error - // Callback that allows user to implement custom behavior // for STUN Binding Requests userBindingRequestHandler func(m *stun.Message, local, remote Candidate, pair *CandidatePair) bool @@ -155,99 +147,6 @@ type Agent struct { proxyDialer proxy.Dialer } -type task struct { - fn func(context.Context, *Agent) - done chan struct{} -} - -// afterRun registers function to be run after the task. -func (a *Agent) afterRun(f func(context.Context)) { - a.muAfterRun.Lock() - a.afterRunFn = append(a.afterRunFn, f) - a.muAfterRun.Unlock() -} - -func (a *Agent) getAfterRunFn() []func(context.Context) { - a.muAfterRun.Lock() - defer a.muAfterRun.Unlock() - fns := a.afterRunFn - a.afterRunFn = nil - return fns -} - -func (a *Agent) ok() error { - select { - case <-a.done: - return a.getErr() - default: - } - return nil -} - -func (a *Agent) getErr() error { - if err := a.err.Load(); err != nil { - return err - } - return ErrClosed -} - -// Run task in serial. Blocking tasks must be cancelable by context. -func (a *Agent) run(ctx context.Context, t func(context.Context, *Agent)) error { - if err := a.ok(); err != nil { - return err - } - done := make(chan struct{}) - select { - case <-ctx.Done(): - return ctx.Err() - case a.chanTask <- task{t, done}: - <-done - return nil - } -} - -// taskLoop handles registered tasks and agent close. -func (a *Agent) taskLoop() { - after := func() { - for { - // Get and run func registered by afterRun(). - fns := a.getAfterRunFn() - if len(fns) == 0 { - break - } - for _, fn := range fns { - fn(a.context()) - } - } - } - defer func() { - a.deleteAllCandidates() - a.startedFn() - - if err := a.buf.Close(); err != nil { - a.log.Warnf("Failed to close buffer: %v", err) - } - - a.closeMulticastConn() - a.updateConnectionState(ConnectionStateClosed) - - after() - - close(a.taskLoopDone) - }() - - for { - select { - case <-a.done: - return - case t := <-a.chanTask: - t.fn(a.context(), a) - close(t.done) - after() - } - } -} - // NewAgent creates a new Agent func NewAgent(config *AgentConfig) (*Agent, error) { //nolint:gocognit var err error @@ -280,7 +179,6 @@ func NewAgent(config *AgentConfig) (*Agent, error) { //nolint:gocognit startedCtx, startedFn := context.WithCancel(context.Background()) a := &Agent{ - chanTask: make(chan task), tieBreaker: globalMathRandomGenerator.Uint64(), lite: config.Lite, gatheringState: GatheringStateNew, @@ -291,8 +189,6 @@ func NewAgent(config *AgentConfig) (*Agent, error) { //nolint:gocognit networkTypes: config.NetworkTypes, onConnected: make(chan struct{}), buf: packetio.NewBuffer(), - done: make(chan struct{}), - taskLoopDone: make(chan struct{}), startedCh: startedCtx.Done(), startedFn: startedFn, portMin: config.PortMin, @@ -340,9 +236,22 @@ func NewAgent(config *AgentConfig) (*Agent, error) { //nolint:gocognit } } + localIfcs, _, err := localInterfaces(a.net, a.interfaceFilter, a.ipFilter, a.networkTypes, a.includeLoopback) + if err != nil { + return nil, fmt.Errorf("error getting local interfaces: %w", err) + } + // Opportunistic mDNS: If we can't open the connection, that's ok: we // can continue without it. - if a.mDNSConn, a.mDNSMode, err = createMulticastDNS(a.net, mDNSMode, mDNSName, log); err != nil { + if a.mDNSConn, a.mDNSMode, err = createMulticastDNS( + a.net, + a.networkTypes, + localIfcs, + a.includeLoopback, + mDNSMode, + mDNSName, + log, + ); err != nil { log.Warnf("Failed to initialize mDNS %s: %v", mDNSName, err) } @@ -358,7 +267,7 @@ func NewAgent(config *AgentConfig) (*Agent, error) { //nolint:gocognit return nil, ErrLiteUsingNonHostCandidates } - if config.Urls != nil && len(config.Urls) > 0 && !containsCandidateType(CandidateTypeServerReflexive, a.candidateTypes) && !containsCandidateType(CandidateTypeRelay, a.candidateTypes) { + if len(config.Urls) > 0 && !containsCandidateType(CandidateTypeServerReflexive, a.candidateTypes) && !containsCandidateType(CandidateTypeRelay, a.candidateTypes) { a.closeMulticastConn() return nil, ErrUselessUrlsProvided } @@ -368,7 +277,23 @@ func NewAgent(config *AgentConfig) (*Agent, error) { //nolint:gocognit return nil, err } - go a.taskLoop() + a.loop = taskloop.New(func() { + a.removeUfragFromMux() + a.deleteAllCandidates() + a.startedFn() + + if err := a.buf.Close(); err != nil { + a.log.Warnf("Failed to close buffer: %v", err) + } + + a.closeMulticastConn() + a.updateConnectionState(ConnectionStateClosed) + + a.gatherCandidateCancel() + if a.gatherCandidateDone != nil { + <-a.gatherCandidateDone + } + }) // Restart is also used to initialize the agent for the first time if err := a.Restart(config.LocalUfrag, config.LocalPwd); err != nil { @@ -394,10 +319,10 @@ func (a *Agent) startConnectivityChecks(isControlling bool, remoteUfrag, remoteP a.log.Debugf("Started agent: isControlling? %t, remoteUfrag: %q, remotePwd: %q", isControlling, remoteUfrag, remotePwd) - return a.run(a.context(), func(ctx context.Context, agent *Agent) { - agent.isControlling = isControlling - agent.remoteUfrag = remoteUfrag - agent.remotePwd = remotePwd + return a.loop.Run(a.loop, func(_ context.Context) { + a.isControlling = isControlling + a.remoteUfrag = remoteUfrag + a.remotePwd = remotePwd if isControlling { a.selector = &controllingSelector{agent: a, log: a.log} @@ -412,7 +337,7 @@ func (a *Agent) startConnectivityChecks(isControlling bool, remoteUfrag, remoteP a.selector.Start() a.startedFn() - agent.updateConnectionState(ConnectionStateChecking) + a.updateConnectionState(ConnectionStateChecking) a.requestConnectivityCheck() go a.connectivityChecks() //nolint:contextcheck @@ -424,7 +349,7 @@ func (a *Agent) connectivityChecks() { checkingDuration := time.Time{} contact := func() { - if err := a.run(a.context(), func(ctx context.Context, a *Agent) { + if err := a.loop.Run(a.loop, func(_ context.Context) { defer func() { lastConnectionState = a.connectionState }() @@ -487,7 +412,7 @@ func (a *Agent) connectivityChecks() { contact() case <-t.C: contact() - case <-a.done: + case <-a.loop.Done(): t.Stop() return } @@ -679,9 +604,9 @@ func (a *Agent) AddRemoteCandidate(c Candidate) error { } go func() { - if err := a.run(a.context(), func(ctx context.Context, agent *Agent) { + if err := a.loop.Run(a.loop, func(_ context.Context) { // nolint: contextcheck - agent.addRemoteCandidate(c) + a.addRemoteCandidate(c) }); err != nil { a.log.Warnf("Failed to add remote candidate %s: %v", c.Address(), err) return @@ -694,26 +619,21 @@ func (a *Agent) resolveAndAddMulticastCandidate(c *CandidateHost) { if a.mDNSConn == nil { return } - _, src, err := a.mDNSConn.Query(c.context(), c.Address()) + + _, src, err := a.mDNSConn.QueryAddr(c.context(), c.Address()) if err != nil { a.log.Warnf("Failed to discover mDNS candidate %s: %v", c.Address(), err) return } - ip, ipOk := parseMulticastAnswerAddr(src) - if !ipOk { - a.log.Warnf("Failed to discover mDNS candidate %s: failed to parse IP", c.Address()) - return - } - - if err = c.setIP(ip); err != nil { + if err = c.setIPAddr(src); err != nil { a.log.Warnf("Failed to discover mDNS candidate %s: %v", c.Address(), err) return } - if err = a.run(a.context(), func(ctx context.Context, agent *Agent) { + if err = a.loop.Run(a.loop, func(_ context.Context) { // nolint: contextcheck - agent.addRemoteCandidate(c) + a.addRemoteCandidate(c) }); err != nil { a.log.Warnf("Failed to add mDNS candidate %s: %v", c.Address(), err) return @@ -728,17 +648,23 @@ func (a *Agent) requestConnectivityCheck() { } func (a *Agent) addRemotePassiveTCPCandidate(remoteCandidate Candidate) { - localIPs, err := localInterfaces(a.net, a.interfaceFilter, a.ipFilter, []NetworkType{remoteCandidate.NetworkType()}, a.includeLoopback) + _, localIPs, err := localInterfaces(a.net, a.interfaceFilter, a.ipFilter, []NetworkType{remoteCandidate.NetworkType()}, a.includeLoopback) if err != nil { a.log.Warnf("Failed to iterate local interfaces, host candidates will not be gathered %s", err) return } for i := range localIPs { + ip, _, _, err := parseAddr(remoteCandidate.addr()) + if err != nil { + a.log.Warnf("Failed to parse address: %s; error: %s", remoteCandidate.addr(), err) + continue + } + conn := newActiveTCPConn( - a.context(), + a.loop, net.JoinHostPort(localIPs[i].String(), "0"), - net.JoinHostPort(remoteCandidate.Address(), strconv.Itoa(remoteCandidate.Port())), + netip.AddrPortFrom(ip, uint16(remoteCandidate.Port())), a.log, ) @@ -778,14 +704,17 @@ func (a *Agent) addRemoteCandidate(c Candidate) { } } - tcpNetworkTypeFound := false - for _, networkType := range a.networkTypes { - if networkType.IsTCP() { - tcpNetworkTypeFound = true + acceptRemotePassiveTCPCandidate := false + // Assert that TCP4 or TCP6 is a enabled NetworkType locally + if !a.disableActiveTCP && c.TCPType() == TCPTypePassive { + for _, networkType := range a.networkTypes { + if c.NetworkType() == networkType { + acceptRemotePassiveTCPCandidate = true + } } } - if !a.disableActiveTCP && tcpNetworkTypeFound && c.TCPType() == TCPTypePassive { + if acceptRemotePassiveTCPCandidate { a.addRemotePassiveTCPCandidate(c) } @@ -804,7 +733,7 @@ func (a *Agent) addRemoteCandidate(c Candidate) { } func (a *Agent) addCandidate(ctx context.Context, c Candidate, candidateConn net.PacketConn) error { - return a.run(ctx, func(ctx context.Context, agent *Agent) { + return a.loop.Run(ctx, func(context.Context) { set := a.localCandidates[c.NetworkType()] for _, candidate := range set { if candidate.Equal(c) { @@ -832,7 +761,9 @@ func (a *Agent) addCandidate(ctx context.Context, c Candidate, candidateConn net a.requestConnectivityCheck() - a.candidateNotifier.EnqueueCandidate(c) + if !c.filterForLocationTracking() { + a.candidateNotifier.EnqueueCandidate(c) + } }) } @@ -840,9 +771,9 @@ func (a *Agent) addCandidate(ctx context.Context, c Candidate, candidateConn net func (a *Agent) GetRemoteCandidates() ([]Candidate, error) { var res []Candidate - err := a.run(a.context(), func(ctx context.Context, agent *Agent) { + err := a.loop.Run(a.loop, func(_ context.Context) { var candidates []Candidate - for _, set := range agent.remoteCandidates { + for _, set := range a.remoteCandidates { candidates = append(candidates, set...) } res = candidates @@ -858,10 +789,15 @@ func (a *Agent) GetRemoteCandidates() ([]Candidate, error) { func (a *Agent) GetLocalCandidates() ([]Candidate, error) { var res []Candidate - err := a.run(a.context(), func(ctx context.Context, agent *Agent) { + err := a.loop.Run(a.loop, func(_ context.Context) { var candidates []Candidate - for _, set := range agent.localCandidates { - candidates = append(candidates, set...) + for _, set := range a.localCandidates { + for _, c := range set { + if c.filterForLocationTracking() { + continue + } + candidates = append(candidates, c) + } } res = candidates }) @@ -875,9 +811,9 @@ func (a *Agent) GetLocalCandidates() ([]Candidate, error) { // GetLocalUserCredentials returns the local user credentials func (a *Agent) GetLocalUserCredentials() (frag string, pwd string, err error) { valSet := make(chan struct{}) - err = a.run(a.context(), func(ctx context.Context, agent *Agent) { - frag = agent.localUfrag - pwd = agent.localPwd + err = a.loop.Run(a.loop, func(_ context.Context) { + frag = a.localUfrag + pwd = a.localPwd close(valSet) }) @@ -890,9 +826,9 @@ func (a *Agent) GetLocalUserCredentials() (frag string, pwd string, err error) { // GetRemoteUserCredentials returns the remote user credentials func (a *Agent) GetRemoteUserCredentials() (frag string, pwd string, err error) { valSet := make(chan struct{}) - err = a.run(a.context(), func(ctx context.Context, agent *Agent) { - frag = agent.remoteUfrag - pwd = agent.remotePwd + err = a.loop.Run(a.loop, func(_ context.Context) { + frag = a.remoteUfrag + pwd = a.remotePwd close(valSet) }) @@ -927,26 +863,8 @@ func (a *Agent) GracefulClose() error { } func (a *Agent) close(graceful bool) error { - if err := a.ok(); err != nil { - if errors.Is(err, ErrClosed) { - return nil - } - return err - } - - a.afterRun(func(context.Context) { - a.gatherCandidateCancel() - if a.gatherCandidateDone != nil { - <-a.gatherCandidateDone - } - }) - a.err.Store(ErrClosed) - - a.removeUfragFromMux() - - close(a.done) // the loop is safe to wait on no matter what - <-a.taskLoopDone + a.loop.Close() // but we are in less control of the notifiers, so we will // pass through `graceful`. @@ -980,9 +898,9 @@ func (a *Agent) deleteAllCandidates() { } func (a *Agent) findRemoteCandidate(networkType NetworkType, addr net.Addr) Candidate { - ip, port, _, ok := parseAddr(addr) - if !ok { - a.log.Warnf("Failed to parse address: %s", addr) + ip, port, _, err := parseAddr(addr) + if err != nil { + a.log.Warnf("Failed to parse address: %s; error: %s", addr, err) return nil } @@ -1012,15 +930,15 @@ func (a *Agent) sendBindingRequest(m *stun.Message, local, remote Candidate) { func (a *Agent) sendBindingSuccess(m *stun.Message, local, remote Candidate) { base := remote - ip, port, _, ok := parseAddr(base.addr()) - if !ok { - a.log.Warnf("Failed to parse address: %s", base.addr()) + ip, port, _, err := parseAddr(base.addr()) + if err != nil { + a.log.Warnf("Failed to parse address: %s; error: %s", base.addr(), err) return } if out, err := stun.Build(m, stun.BindingSuccess, &stun.XORMappedAddress{ - IP: ip, + IP: ip.AsSlice(), Port: port, }, stun.NewShortTermIntegrity(a.localPwd), @@ -1122,9 +1040,9 @@ func (a *Agent) handleInbound(m *stun.Message, local Candidate, remote net.Addr) } if remoteCandidate == nil { - ip, port, networkType, ok := parseAddr(remote) - if !ok { - a.log.Errorf("Failed to create parse remote net.Addr when creating remote prflx candidate") + ip, port, networkType, err := parseAddr(remote) + if err != nil { + a.log.Errorf("Failed to create parse remote net.Addr when creating remote prflx candidate: %s", err) return } @@ -1160,7 +1078,7 @@ func (a *Agent) handleInbound(m *stun.Message, local Candidate, remote net.Addr) // and returns true if it is an actual remote candidate func (a *Agent) validateNonSTUNTraffic(local Candidate, remote net.Addr) (Candidate, bool) { var remoteCandidate Candidate - if err := a.run(local.context(), func(ctx context.Context, agent *Agent) { + if err := a.loop.Run(local.context(), func(context.Context) { remoteCandidate = a.findRemoteCandidate(local.NetworkType(), remote) if remoteCandidate != nil { remoteCandidate.seen(false) @@ -1217,9 +1135,9 @@ func (a *Agent) SetRemoteCredentials(remoteUfrag, remotePwd string) error { return ErrRemotePwdEmpty } - return a.run(a.context(), func(ctx context.Context, agent *Agent) { - agent.remoteUfrag = remoteUfrag - agent.remotePwd = remotePwd + return a.loop.Run(a.loop, func(_ context.Context) { + a.remoteUfrag = remoteUfrag + a.remotePwd = remotePwd }) } @@ -1254,17 +1172,17 @@ func (a *Agent) Restart(ufrag, pwd string) error { } var err error - if runErr := a.run(a.context(), func(ctx context.Context, agent *Agent) { - if agent.gatheringState == GatheringStateGathering { - agent.gatherCandidateCancel() + if runErr := a.loop.Run(a.loop, func(_ context.Context) { + if a.gatheringState == GatheringStateGathering { + a.gatherCandidateCancel() } // Clear all agent needed to take back to fresh state a.removeUfragFromMux() - agent.localUfrag = ufrag - agent.localPwd = pwd - agent.remoteUfrag = "" - agent.remotePwd = "" + a.localUfrag = ufrag + a.localPwd = pwd + a.remoteUfrag = "" + a.remotePwd = "" a.gatheringState = GatheringStateNew a.checklist = make([]*CandidatePair, 0) a.pendingBindingRequests = make([]bindingRequest, 0) @@ -1287,7 +1205,7 @@ func (a *Agent) Restart(ufrag, pwd string) error { func (a *Agent) setGatheringState(newState GatheringState) error { done := make(chan struct{}) - if err := a.run(a.context(), func(ctx context.Context, agent *Agent) { + if err := a.loop.Run(a.loop, func(context.Context) { if a.gatheringState != newState && newState == GatheringStateComplete { a.candidateNotifier.EnqueueCandidate(nil) } diff --git a/vendor/github.com/pion/ice/v2/agent_config.go b/vendor/github.com/pion/ice/v4/agent_config.go similarity index 93% rename from vendor/github.com/pion/ice/v2/agent_config.go rename to vendor/github.com/pion/ice/v4/agent_config.go index 7f7b67a3ec..93e88890ad 100644 --- a/vendor/github.com/pion/ice/v2/agent_config.go +++ b/vendor/github.com/pion/ice/v4/agent_config.go @@ -8,8 +8,8 @@ import ( "time" "github.com/pion/logging" - "github.com/pion/stun" - "github.com/pion/transport/v2" + "github.com/pion/stun/v3" + "github.com/pion/transport/v3" "golang.org/x/net/proxy" ) @@ -38,6 +38,9 @@ const ( // defaultRelayAcceptanceMinWait is the wait time before nominating a relay candidate defaultRelayAcceptanceMinWait = 2000 * time.Millisecond + // defaultSTUNGatherTimeout is the wait time for STUN responses + defaultSTUNGatherTimeout = 5 * time.Second + // defaultMaxBindingRequests is the maximum number of binding requests before considering a pair failed defaultMaxBindingRequests = 7 @@ -130,12 +133,14 @@ type AgentConfig struct { // HostAcceptanceMinWait specify a minimum wait time before selecting host candidates HostAcceptanceMinWait *time.Duration - // HostAcceptanceMinWait specify a minimum wait time before selecting srflx candidates + // SrflxAcceptanceMinWait specify a minimum wait time before selecting srflx candidates SrflxAcceptanceMinWait *time.Duration - // HostAcceptanceMinWait specify a minimum wait time before selecting prflx candidates + // PrflxAcceptanceMinWait specify a minimum wait time before selecting prflx candidates PrflxAcceptanceMinWait *time.Duration - // HostAcceptanceMinWait specify a minimum wait time before selecting relay candidates + // RelayAcceptanceMinWait specify a minimum wait time before selecting relay candidates RelayAcceptanceMinWait *time.Duration + // STUNGatherTimeout specify a minimum wait time for STUN responses + STUNGatherTimeout *time.Duration // Net is the our abstracted network interface for internal development purpose only // (see https://github.com/pion/transport) @@ -229,6 +234,12 @@ func (config *AgentConfig) initWithDefaults(a *Agent) { a.relayAcceptanceMinWait = *config.RelayAcceptanceMinWait } + if config.STUNGatherTimeout == nil { + a.stunGatherTimeout = defaultSTUNGatherTimeout + } else { + a.stunGatherTimeout = *config.STUNGatherTimeout + } + if config.TCPPriorityOffset == nil { a.tcpPriorityOffset = defaultTCPPriorityOffset } else { @@ -259,7 +270,7 @@ func (config *AgentConfig) initWithDefaults(a *Agent) { a.checkInterval = *config.CheckInterval } - if config.CandidateTypes == nil || len(config.CandidateTypes) == 0 { + if len(config.CandidateTypes) == 0 { a.candidateTypes = defaultCandidateTypes() } else { a.candidateTypes = config.CandidateTypes diff --git a/vendor/github.com/pion/ice/v2/agent_handlers.go b/vendor/github.com/pion/ice/v4/agent_handlers.go similarity index 100% rename from vendor/github.com/pion/ice/v2/agent_handlers.go rename to vendor/github.com/pion/ice/v4/agent_handlers.go diff --git a/vendor/github.com/pion/ice/v2/agent_stats.go b/vendor/github.com/pion/ice/v4/agent_stats.go similarity index 87% rename from vendor/github.com/pion/ice/v2/agent_stats.go rename to vendor/github.com/pion/ice/v4/agent_stats.go index 9344ec3a37..b18c13818e 100644 --- a/vendor/github.com/pion/ice/v2/agent_stats.go +++ b/vendor/github.com/pion/ice/v4/agent_stats.go @@ -11,9 +11,9 @@ import ( // GetCandidatePairsStats returns a list of candidate pair stats func (a *Agent) GetCandidatePairsStats() []CandidatePairStats { var res []CandidatePairStats - err := a.run(a.context(), func(ctx context.Context, agent *Agent) { - result := make([]CandidatePairStats, 0, len(agent.checklist)) - for _, cp := range agent.checklist { + err := a.loop.Run(a.loop, func(_ context.Context) { + result := make([]CandidatePairStats, 0, len(a.checklist)) + for _, cp := range a.checklist { stat := CandidatePairStats{ Timestamp: time.Now(), LocalCandidateID: cp.Local.ID(), @@ -59,8 +59,8 @@ func (a *Agent) GetCandidatePairsStats() []CandidatePairStats { func (a *Agent) GetSelectedCandidatePairStats() (CandidatePairStats, bool) { isAvailable := false var res CandidatePairStats - err := a.run(a.context(), func(ctx context.Context, agent *Agent) { - sp := agent.getSelectedPair() + err := a.loop.Run(a.loop, func(_ context.Context) { + sp := a.getSelectedPair() if sp == nil { return } @@ -107,9 +107,9 @@ func (a *Agent) GetSelectedCandidatePairStats() (CandidatePairStats, bool) { // GetLocalCandidatesStats returns a list of local candidates stats func (a *Agent) GetLocalCandidatesStats() []CandidateStats { var res []CandidateStats - err := a.run(a.context(), func(ctx context.Context, agent *Agent) { - result := make([]CandidateStats, 0, len(agent.localCandidates)) - for networkType, localCandidates := range agent.localCandidates { + err := a.loop.Run(a.loop, func(_ context.Context) { + result := make([]CandidateStats, 0, len(a.localCandidates)) + for networkType, localCandidates := range a.localCandidates { for _, c := range localCandidates { relayProtocol := "" if c.Type() == CandidateTypeRelay { @@ -144,9 +144,9 @@ func (a *Agent) GetLocalCandidatesStats() []CandidateStats { // GetRemoteCandidatesStats returns a list of remote candidates stats func (a *Agent) GetRemoteCandidatesStats() []CandidateStats { var res []CandidateStats - err := a.run(a.context(), func(ctx context.Context, agent *Agent) { - result := make([]CandidateStats, 0, len(agent.remoteCandidates)) - for networkType, remoteCandidates := range agent.remoteCandidates { + err := a.loop.Run(a.loop, func(_ context.Context) { + result := make([]CandidateStats, 0, len(a.remoteCandidates)) + for networkType, remoteCandidates := range a.remoteCandidates { for _, c := range remoteCandidates { stat := CandidateStats{ Timestamp: time.Now(), diff --git a/vendor/github.com/pion/ice/v2/candidate.go b/vendor/github.com/pion/ice/v4/candidate.go similarity index 98% rename from vendor/github.com/pion/ice/v2/candidate.go rename to vendor/github.com/pion/ice/v4/candidate.go index 92a0076883..4324159b45 100644 --- a/vendor/github.com/pion/ice/v2/candidate.go +++ b/vendor/github.com/pion/ice/v4/candidate.go @@ -61,6 +61,7 @@ type Candidate interface { Marshal() string addr() net.Addr + filterForLocationTracking() bool agent() *Agent context() context.Context diff --git a/vendor/github.com/pion/ice/v2/candidate_base.go b/vendor/github.com/pion/ice/v4/candidate_base.go similarity index 95% rename from vendor/github.com/pion/ice/v2/candidate_base.go rename to vendor/github.com/pion/ice/v4/candidate_base.go index f725985218..7d0636858d 100644 --- a/vendor/github.com/pion/ice/v2/candidate_base.go +++ b/vendor/github.com/pion/ice/v4/candidate_base.go @@ -15,7 +15,7 @@ import ( "sync/atomic" "time" - "github.com/pion/stun" + "github.com/pion/stun/v3" ) type candidateBase struct { @@ -43,6 +43,7 @@ type candidateBase struct { priorityOverride uint32 remoteCandidateCaches map[AddrPort]Candidate + isLocationTracked bool } // Done implements context.Context @@ -267,7 +268,7 @@ func (c *candidateBase) handleInboundPacket(buf []byte, srcAddr net.Addr) { return } - if err := a.run(c, func(ctx context.Context, a *Agent) { + if err := a.loop.Run(c, func(_ context.Context) { // nolint: contextcheck a.handleInbound(m, c, srcAddr) }); err != nil { @@ -384,6 +385,14 @@ func (c *candidateBase) Priority() uint32 { // Equal is used to compare two candidateBases func (c *candidateBase) Equal(other Candidate) bool { + if c.addr() != other.addr() { + if c.addr() == nil || other.addr() == nil { + return false + } + if c.addr().String() != other.addr().String() { + return false + } + } return c.NetworkType() == other.NetworkType() && c.Type() == other.Type() && c.Address() == other.Address() && @@ -394,7 +403,7 @@ func (c *candidateBase) Equal(other Candidate) bool { // String makes the candidateBase printable func (c *candidateBase) String() string { - return fmt.Sprintf("%s %s %s%s", c.NetworkType(), c.Type(), net.JoinHostPort(c.Address(), strconv.Itoa(c.Port())), c.relatedAddress) + return fmt.Sprintf("%s %s %s%s (resolved: %v)", c.NetworkType(), c.Type(), net.JoinHostPort(c.Address(), strconv.Itoa(c.Port())), c.relatedAddress, c.resolvedAddr) } // LastReceived returns a time.Time indicating the last time @@ -435,6 +444,10 @@ func (c *candidateBase) addr() net.Addr { return c.resolvedAddr } +func (c *candidateBase) filterForLocationTracking() bool { + return c.isLocationTracked +} + func (c *candidateBase) agent() *Agent { return c.currAgent } @@ -558,7 +571,7 @@ func UnmarshalCandidate(raw string) (Candidate, error) { switch typ { case "host": - return NewCandidateHost(&CandidateHostConfig{"", protocol, address, port, component, priority, foundation, tcpType}) + return NewCandidateHost(&CandidateHostConfig{"", protocol, address, port, component, priority, foundation, tcpType, false}) case "srflx": return NewCandidateServerReflexive(&CandidateServerReflexiveConfig{"", protocol, address, port, component, priority, foundation, relatedAddress, relatedPort}) case "prflx": diff --git a/vendor/github.com/pion/ice/v2/candidate_host.go b/vendor/github.com/pion/ice/v4/candidate_host.go similarity index 69% rename from vendor/github.com/pion/ice/v2/candidate_host.go rename to vendor/github.com/pion/ice/v4/candidate_host.go index 5d207dd91f..c14b6a7c63 100644 --- a/vendor/github.com/pion/ice/v2/candidate_host.go +++ b/vendor/github.com/pion/ice/v4/candidate_host.go @@ -4,7 +4,7 @@ package ice import ( - "net" + "net/netip" "strings" ) @@ -17,14 +17,15 @@ type CandidateHost struct { // CandidateHostConfig is the config required to create a new CandidateHost type CandidateHostConfig struct { - CandidateID string - Network string - Address string - Port int - Component uint16 - Priority uint32 - Foundation string - TCPType TCPType + CandidateID string + Network string + Address string + Port int + Component uint16 + Priority uint32 + Foundation string + TCPType TCPType + IsLocationTracked bool } // NewCandidateHost creates a new host candidate @@ -46,17 +47,18 @@ func NewCandidateHost(config *CandidateHostConfig) (*CandidateHost, error) { foundationOverride: config.Foundation, priorityOverride: config.Priority, remoteCandidateCaches: map[AddrPort]Candidate{}, + isLocationTracked: config.IsLocationTracked, }, network: config.Network, } if !strings.HasSuffix(config.Address, ".local") { - ip := net.ParseIP(config.Address) - if ip == nil { - return nil, ErrAddressParseFailed + ipAddr, err := netip.ParseAddr(config.Address) + if err != nil { + return nil, err } - if err := c.setIP(ip); err != nil { + if err := c.setIPAddr(ipAddr); err != nil { return nil, err } } else { @@ -67,14 +69,14 @@ func NewCandidateHost(config *CandidateHostConfig) (*CandidateHost, error) { return c, nil } -func (c *CandidateHost) setIP(ip net.IP) error { - networkType, err := determineNetworkType(c.network, ip) +func (c *CandidateHost) setIPAddr(addr netip.Addr) error { + networkType, err := determineNetworkType(c.network, addr) if err != nil { return err } c.candidateBase.networkType = networkType - c.candidateBase.resolvedAddr = createAddr(networkType, ip, c.port) + c.candidateBase.resolvedAddr = createAddr(networkType, addr, c.port) return nil } diff --git a/vendor/github.com/pion/ice/v2/candidate_peer_reflexive.go b/vendor/github.com/pion/ice/v4/candidate_peer_reflexive.go similarity index 85% rename from vendor/github.com/pion/ice/v2/candidate_peer_reflexive.go rename to vendor/github.com/pion/ice/v4/candidate_peer_reflexive.go index bbcfe3358b..b28e9a76fc 100644 --- a/vendor/github.com/pion/ice/v2/candidate_peer_reflexive.go +++ b/vendor/github.com/pion/ice/v4/candidate_peer_reflexive.go @@ -6,7 +6,9 @@ //nolint:dupl package ice -import "net" +import ( + "net/netip" +) // CandidatePeerReflexive ... type CandidatePeerReflexive struct { @@ -28,12 +30,12 @@ type CandidatePeerReflexiveConfig struct { // NewCandidatePeerReflexive creates a new peer reflective candidate func NewCandidatePeerReflexive(config *CandidatePeerReflexiveConfig) (*CandidatePeerReflexive, error) { - ip := net.ParseIP(config.Address) - if ip == nil { - return nil, ErrAddressParseFailed + ipAddr, err := netip.ParseAddr(config.Address) + if err != nil { + return nil, err } - networkType, err := determineNetworkType(config.Network, ip) + networkType, err := determineNetworkType(config.Network, ipAddr) if err != nil { return nil, err } @@ -50,7 +52,7 @@ func NewCandidatePeerReflexive(config *CandidatePeerReflexiveConfig) (*Candidate candidateType: CandidateTypePeerReflexive, address: config.Address, port: config.Port, - resolvedAddr: createAddr(networkType, ip, config.Port), + resolvedAddr: createAddr(networkType, ipAddr, config.Port), component: config.Component, foundationOverride: config.Foundation, priorityOverride: config.Priority, diff --git a/vendor/github.com/pion/ice/v2/candidate_relay.go b/vendor/github.com/pion/ice/v4/candidate_relay.go similarity index 84% rename from vendor/github.com/pion/ice/v2/candidate_relay.go rename to vendor/github.com/pion/ice/v4/candidate_relay.go index fa5297b25a..faf281b0d2 100644 --- a/vendor/github.com/pion/ice/v2/candidate_relay.go +++ b/vendor/github.com/pion/ice/v4/candidate_relay.go @@ -5,6 +5,7 @@ package ice import ( "net" + "net/netip" ) // CandidateRelay ... @@ -38,24 +39,28 @@ func NewCandidateRelay(config *CandidateRelayConfig) (*CandidateRelay, error) { candidateID = globalCandidateIDGenerator.Generate() } - ip := net.ParseIP(config.Address) - if ip == nil { - return nil, ErrAddressParseFailed + ipAddr, err := netip.ParseAddr(config.Address) + if err != nil { + return nil, err } - networkType, err := determineNetworkType(config.Network, ip) + networkType, err := determineNetworkType(config.Network, ipAddr) if err != nil { return nil, err } return &CandidateRelay{ candidateBase: candidateBase{ - id: candidateID, - networkType: networkType, - candidateType: CandidateTypeRelay, - address: config.Address, - port: config.Port, - resolvedAddr: &net.UDPAddr{IP: ip, Port: config.Port}, + id: candidateID, + networkType: networkType, + candidateType: CandidateTypeRelay, + address: config.Address, + port: config.Port, + resolvedAddr: &net.UDPAddr{ + IP: ipAddr.AsSlice(), + Port: config.Port, + Zone: ipAddr.Zone(), + }, component: config.Component, foundationOverride: config.Foundation, priorityOverride: config.Priority, diff --git a/vendor/github.com/pion/ice/v2/candidate_server_reflexive.go b/vendor/github.com/pion/ice/v4/candidate_server_reflexive.go similarity index 72% rename from vendor/github.com/pion/ice/v2/candidate_server_reflexive.go rename to vendor/github.com/pion/ice/v4/candidate_server_reflexive.go index 3a8ac0ff7f..85d613e2dc 100644 --- a/vendor/github.com/pion/ice/v2/candidate_server_reflexive.go +++ b/vendor/github.com/pion/ice/v4/candidate_server_reflexive.go @@ -3,7 +3,10 @@ package ice -import "net" +import ( + "net" + "net/netip" +) // CandidateServerReflexive ... type CandidateServerReflexive struct { @@ -25,12 +28,12 @@ type CandidateServerReflexiveConfig struct { // NewCandidateServerReflexive creates a new server reflective candidate func NewCandidateServerReflexive(config *CandidateServerReflexiveConfig) (*CandidateServerReflexive, error) { - ip := net.ParseIP(config.Address) - if ip == nil { - return nil, ErrAddressParseFailed + ipAddr, err := netip.ParseAddr(config.Address) + if err != nil { + return nil, err } - networkType, err := determineNetworkType(config.Network, ip) + networkType, err := determineNetworkType(config.Network, ipAddr) if err != nil { return nil, err } @@ -42,12 +45,16 @@ func NewCandidateServerReflexive(config *CandidateServerReflexiveConfig) (*Candi return &CandidateServerReflexive{ candidateBase: candidateBase{ - id: candidateID, - networkType: networkType, - candidateType: CandidateTypeServerReflexive, - address: config.Address, - port: config.Port, - resolvedAddr: &net.UDPAddr{IP: ip, Port: config.Port}, + id: candidateID, + networkType: networkType, + candidateType: CandidateTypeServerReflexive, + address: config.Address, + port: config.Port, + resolvedAddr: &net.UDPAddr{ + IP: ipAddr.AsSlice(), + Port: config.Port, + Zone: ipAddr.Zone(), + }, component: config.Component, foundationOverride: config.Foundation, priorityOverride: config.Priority, diff --git a/vendor/github.com/pion/ice/v2/candidatepair.go b/vendor/github.com/pion/ice/v4/candidatepair.go similarity index 95% rename from vendor/github.com/pion/ice/v2/candidatepair.go rename to vendor/github.com/pion/ice/v4/candidatepair.go index 38f8ccb933..2b27eb1832 100644 --- a/vendor/github.com/pion/ice/v2/candidatepair.go +++ b/vendor/github.com/pion/ice/v4/candidatepair.go @@ -8,7 +8,7 @@ import ( "sync/atomic" "time" - "github.com/pion/stun" + "github.com/pion/stun/v3" ) func newCandidatePair(local, remote Candidate, controlling bool) *CandidatePair { @@ -73,13 +73,13 @@ func (p *CandidatePair) priority() uint64 { // Just implement these here rather // than fooling around with the math package - min := func(x, y uint32) uint64 { + localMin := func(x, y uint32) uint64 { if x < y { return uint64(x) } return uint64(y) } - max := func(x, y uint32) uint64 { + localMax := func(x, y uint32) uint64 { if x > y { return uint64(x) } @@ -94,7 +94,7 @@ func (p *CandidatePair) priority() uint64 { // 1<<32 overflows uint32; and if both g && d are // maxUint32, this result would overflow uint64 - return (1<<32-1)*min(g, d) + 2*max(g, d) + cmp(g, d) + return (1<<32-1)*localMin(g, d) + 2*localMax(g, d) + cmp(g, d) } func (p *CandidatePair) Write(b []byte) (int, error) { diff --git a/vendor/github.com/pion/ice/v2/candidatepair_state.go b/vendor/github.com/pion/ice/v4/candidatepair_state.go similarity index 95% rename from vendor/github.com/pion/ice/v2/candidatepair_state.go rename to vendor/github.com/pion/ice/v4/candidatepair_state.go index 1a1e827b01..b7f0dd8735 100644 --- a/vendor/github.com/pion/ice/v2/candidatepair_state.go +++ b/vendor/github.com/pion/ice/v4/candidatepair_state.go @@ -9,7 +9,7 @@ type CandidatePairState int const ( // CandidatePairStateWaiting means a check has not been performed for // this pair - CandidatePairStateWaiting = iota + 1 + CandidatePairStateWaiting CandidatePairState = iota + 1 // CandidatePairStateInProgress means a check has been sent for this pair, // but the transaction is in progress. diff --git a/vendor/github.com/pion/ice/v2/candidaterelatedaddress.go b/vendor/github.com/pion/ice/v4/candidaterelatedaddress.go similarity index 100% rename from vendor/github.com/pion/ice/v2/candidaterelatedaddress.go rename to vendor/github.com/pion/ice/v4/candidaterelatedaddress.go diff --git a/vendor/github.com/pion/ice/v2/candidatetype.go b/vendor/github.com/pion/ice/v4/candidatetype.go similarity index 100% rename from vendor/github.com/pion/ice/v2/candidatetype.go rename to vendor/github.com/pion/ice/v4/candidatetype.go diff --git a/vendor/github.com/pion/ice/v2/codecov.yml b/vendor/github.com/pion/ice/v4/codecov.yml similarity index 100% rename from vendor/github.com/pion/ice/v2/codecov.yml rename to vendor/github.com/pion/ice/v4/codecov.yml diff --git a/vendor/github.com/pion/ice/v2/errors.go b/vendor/github.com/pion/ice/v4/errors.go similarity index 96% rename from vendor/github.com/pion/ice/v2/errors.go rename to vendor/github.com/pion/ice/v4/errors.go index 46785edbe3..02736ccbf3 100644 --- a/vendor/github.com/pion/ice/v2/errors.go +++ b/vendor/github.com/pion/ice/v4/errors.go @@ -3,7 +3,11 @@ package ice -import "errors" +import ( + "errors" + + "github.com/pion/ice/v4/internal/taskloop" +) var ( // ErrUnknownType indicates an error with Unknown info. @@ -36,7 +40,7 @@ var ( ErrProtoType = errors.New("invalid transport protocol type") // ErrClosed indicates the agent is closed - ErrClosed = errors.New("the agent is closed") + ErrClosed = taskloop.ErrClosed // ErrNoCandidatePairs indicates agent does not have a valid candidate pair ErrNoCandidatePairs = errors.New("no candidate pairs available") @@ -133,6 +137,8 @@ var ( errWriteSTUNMessage = errors.New("failed to send STUN message") errWriteSTUNMessageToIceConn = errors.New("failed to write STUN message to ICE connection") errXORMappedAddrTimeout = errors.New("timeout while waiting for XORMappedAddr") + errFailedToCastUDPAddr = errors.New("failed to cast net.Addr to net.UDPAddr") + errInvalidIPAddress = errors.New("invalid ip address") // UDPMuxDefault should not listen on unspecified address, but to keep backward compatibility, don't return error now. // will be used in the future. diff --git a/vendor/github.com/pion/ice/v2/external_ip_mapper.go b/vendor/github.com/pion/ice/v4/external_ip_mapper.go similarity index 100% rename from vendor/github.com/pion/ice/v2/external_ip_mapper.go rename to vendor/github.com/pion/ice/v4/external_ip_mapper.go diff --git a/vendor/github.com/pion/ice/v2/gather.go b/vendor/github.com/pion/ice/v4/gather.go similarity index 80% rename from vendor/github.com/pion/ice/v2/gather.go rename to vendor/github.com/pion/ice/v4/gather.go index 3ca8086e79..99b5c06904 100644 --- a/vendor/github.com/pion/ice/v2/gather.go +++ b/vendor/github.com/pion/ice/v4/gather.go @@ -9,20 +9,16 @@ import ( "fmt" "io" "net" + "net/netip" "reflect" "sync" - "time" - "github.com/pion/dtls/v2" - "github.com/pion/ice/v2/internal/fakenet" - stunx "github.com/pion/ice/v2/internal/stun" + "github.com/pion/dtls/v3" + "github.com/pion/ice/v4/internal/fakenet" + stunx "github.com/pion/ice/v4/internal/stun" "github.com/pion/logging" - "github.com/pion/stun" - "github.com/pion/turn/v2" -) - -const ( - stunGatherTimeout = time.Second * 5 + "github.com/pion/stun/v3" + "github.com/pion/turn/v4" ) // Close a net.Conn and log if we have a failure @@ -42,7 +38,7 @@ func closeConnAndLog(c io.Closer, log logging.LeveledLogger, msg string, args .. func (a *Agent) GatherCandidates() error { var gatherErr error - if runErr := a.run(a.context(), func(ctx context.Context, agent *Agent) { + if runErr := a.loop.Run(a.loop, func(ctx context.Context) { if a.gatheringState != GatheringStateNew { gatherErr = ErrMultipleGatherAttempted return @@ -133,25 +129,37 @@ func (a *Agent) gatherCandidatesLocal(ctx context.Context, networkTypes []Networ delete(networks, udp) } - localIPs, err := localInterfaces(a.net, a.interfaceFilter, a.ipFilter, networkTypes, a.includeLoopback) + _, localAddrs, err := localInterfaces(a.net, a.interfaceFilter, a.ipFilter, networkTypes, a.includeLoopback) if err != nil { a.log.Warnf("Failed to iterate local interfaces, host candidates will not be gathered %s", err) return } - for _, ip := range localIPs { - mappedIP := ip + for _, addr := range localAddrs { + mappedIP := addr if a.mDNSMode != MulticastDNSModeQueryAndGather && a.extIPMapper != nil && a.extIPMapper.candidateType == CandidateTypeHost { - if _mappedIP, innerErr := a.extIPMapper.findExternalIP(ip.String()); innerErr == nil { - mappedIP = _mappedIP + if _mappedIP, innerErr := a.extIPMapper.findExternalIP(addr.String()); innerErr == nil { + conv, ok := netip.AddrFromSlice(_mappedIP) + if !ok { + a.log.Warnf("failed to convert mapped external IP to netip.Addr'%s'", addr.String()) + continue + } + // we'd rather have an IPv4-mapped IPv6 become IPv4 so that it is usable + mappedIP = conv.Unmap() } else { - a.log.Warnf("1:1 NAT mapping is enabled but no external IP is found for %s", ip.String()) + a.log.Warnf("1:1 NAT mapping is enabled but no external IP is found for %s", addr.String()) } } address := mappedIP.String() + var isLocationTracked bool if a.mDNSMode == MulticastDNSModeQueryAndGather { address = a.mDNSName + } else { + // Here, we are not doing multicast gathering, so we will need to skip this address so + // that we don't accidentally reveal location tracking information. Otherwise, the + // case above hides the IP behind an mDNS address. + isLocationTracked = shouldFilterLocationTrackedIP(mappedIP) } for network := range networks { @@ -174,16 +182,18 @@ func (a *Agent) gatherCandidatesLocal(ctx context.Context, networkTypes []Networ var muxConns []net.PacketConn if multi, ok := a.tcpMux.(AllConnsGetter); ok { a.log.Debugf("GetAllConns by ufrag: %s", a.localUfrag) - muxConns, err = multi.GetAllConns(a.localUfrag, mappedIP.To4() == nil, ip) + // Note: this is missing zone for IPv6 by just grabbing the IP slice + muxConns, err = multi.GetAllConns(a.localUfrag, mappedIP.Is6(), addr.AsSlice()) if err != nil { - a.log.Warnf("Failed to get all TCP connections by ufrag: %s %s %s", network, ip, a.localUfrag) + a.log.Warnf("Failed to get all TCP connections by ufrag: %s %s %s", network, addr, a.localUfrag) continue } } else { a.log.Debugf("GetConn by ufrag: %s", a.localUfrag) - conn, err := a.tcpMux.GetConnByUfrag(a.localUfrag, mappedIP.To4() == nil, ip) + // Note: this is missing zone for IPv6 by just grabbing the IP slice + conn, err := a.tcpMux.GetConnByUfrag(a.localUfrag, mappedIP.Is6(), addr.AsSlice()) if err != nil { - a.log.Warnf("Failed to get TCP connections by ufrag: %s %s %s", network, ip, a.localUfrag) + a.log.Warnf("Failed to get TCP connections by ufrag: %s %s %s", network, addr, a.localUfrag) continue } muxConns = []net.PacketConn{conn} @@ -194,7 +204,7 @@ func (a *Agent) gatherCandidatesLocal(ctx context.Context, networkTypes []Networ if tcpConn, ok := conn.LocalAddr().(*net.TCPAddr); ok { conns = append(conns, connAndPort{conn, tcpConn.Port}) } else { - a.log.Warnf("Failed to get port of connection from TCPMux: %s %s %s", network, ip, a.localUfrag) + a.log.Warnf("Failed to get port of connection from TCPMux: %s %s %s", network, addr, a.localUfrag) } } if len(conns) == 0 { @@ -205,16 +215,20 @@ func (a *Agent) gatherCandidatesLocal(ctx context.Context, networkTypes []Networ // Is there a way to verify that the listen address is even // accessible from the current interface. case udp: - conn, err := listenUDPInPortRange(a.net, a.log, int(a.portMax), int(a.portMin), network, &net.UDPAddr{IP: ip, Port: 0}) + conn, err := listenUDPInPortRange(a.net, a.log, int(a.portMax), int(a.portMin), network, &net.UDPAddr{ + IP: addr.AsSlice(), + Port: 0, + Zone: addr.Zone(), + }) if err != nil { - a.log.Warnf("Failed to listen %s %s", network, ip) + a.log.Warnf("Failed to listen %s %s", network, addr) continue } if udpConn, ok := conn.LocalAddr().(*net.UDPAddr); ok { conns = append(conns, connAndPort{conn, udpConn.Port}) } else { - a.log.Warnf("Failed to get port of UDPAddr from ListenUDPInPortRange: %s %s %s", network, ip, a.localUfrag) + a.log.Warnf("Failed to get port of UDPAddr from ListenUDPInPortRange: %s %s %s", network, addr, a.localUfrag) continue } } @@ -226,6 +240,9 @@ func (a *Agent) gatherCandidatesLocal(ctx context.Context, networkTypes []Networ Port: connAndPort.port, Component: ComponentRTP, TCPType: tcpType, + // we will still process this candidate so that we start up the right + // listeners. + IsLocationTracked: isLocationTracked, } c, err := NewCandidateHost(&hostConfig) @@ -235,7 +252,7 @@ func (a *Agent) gatherCandidatesLocal(ctx context.Context, networkTypes []Networ } if a.mDNSMode == MulticastDNSModeQueryAndGather { - if err = c.setIP(ip); err != nil { + if err = c.setIPAddr(addr); err != nil { closeConnAndLog(connAndPort.conn, a.log, "failed to create host candidate: %s %s %d: %v", network, mappedIP, connAndPort.port, err) continue } @@ -252,6 +269,27 @@ func (a *Agent) gatherCandidatesLocal(ctx context.Context, networkTypes []Networ } } +// shouldFilterLocationTrackedIP returns if this candidate IP should be filtered out from +// any candidate publishing/notification for location tracking reasons. +func shouldFilterLocationTrackedIP(candidateIP netip.Addr) bool { + // https://tools.ietf.org/html/rfc8445#section-5.1.1.1 + // Similarly, when host candidates corresponding to + // an IPv6 address generated using a mechanism that prevents location + // tracking are gathered, then host candidates corresponding to IPv6 + // link-local addresses [RFC4291] MUST NOT be gathered. + return candidateIP.Is6() && (candidateIP.IsLinkLocalUnicast() || candidateIP.IsLinkLocalMulticast()) +} + +// shouldFilterLocationTracked returns if this candidate IP should be filtered out from +// any candidate publishing/notification for location tracking reasons. +func shouldFilterLocationTracked(candidateIP net.IP) bool { + addr, ok := netip.AddrFromSlice(candidateIP) + if !ok { + return false + } + return shouldFilterLocationTrackedIP(addr) +} + func (a *Agent) gatherCandidatesLocalUDPMux(ctx context.Context) error { //nolint:gocognit if a.udpMux == nil { return errUDPMuxDisabled @@ -266,7 +304,16 @@ func (a *Agent) gatherCandidatesLocalUDPMux(ctx context.Context) error { //nolin return errInvalidAddress } candidateIP := udpAddr.IP - if a.extIPMapper != nil && a.extIPMapper.candidateType == CandidateTypeHost { + + if _, ok := a.udpMux.(*UDPMuxDefault); ok && !a.includeLoopback && candidateIP.IsLoopback() { + // Unlike MultiUDPMux Default, UDPMuxDefault doesn't have + // a separate param to include loopback, so we respect agent config + continue + } + + if a.mDNSMode != MulticastDNSModeQueryAndGather && + a.extIPMapper != nil && + a.extIPMapper.candidateType == CandidateTypeHost { mappedIP, err := a.extIPMapper.findExternalIP(candidateIP.String()) if err != nil { a.log.Warnf("1:1 NAT mapping is enabled but no external IP is found for %s", candidateIP.String()) @@ -276,11 +323,24 @@ func (a *Agent) gatherCandidatesLocalUDPMux(ctx context.Context) error { //nolin candidateIP = mappedIP } + var address string + var isLocationTracked bool + if a.mDNSMode == MulticastDNSModeQueryAndGather { + address = a.mDNSName + } else { + address = candidateIP.String() + // Here, we are not doing multicast gathering, so we will need to skip this address so + // that we don't accidentally reveal location tracking information. Otherwise, the + // case above hides the IP behind an mDNS address. + isLocationTracked = shouldFilterLocationTracked(candidateIP) + } + hostConfig := CandidateHostConfig{ - Network: udp, - Address: candidateIP.String(), - Port: udpAddr.Port, - Component: ComponentRTP, + Network: udp, + Address: address, + Port: udpAddr.Port, + Component: ComponentRTP, + IsLocationTracked: isLocationTracked, } // Detect a duplicate candidate before calling addCandidate(). @@ -349,6 +409,11 @@ func (a *Agent) gatherCandidatesSrflxMapped(ctx context.Context, networkTypes [] return } + if shouldFilterLocationTracked(mappedIP) { + closeConnAndLog(conn, a.log, "external IP is somehow filtered for location tracking reasons %s", mappedIP) + return + } + srflxConfig := CandidateServerReflexiveConfig{ Network: network, Address: mappedIP.String(), @@ -404,7 +469,12 @@ func (a *Agent) gatherCandidatesSrflxUDPMux(ctx context.Context, urls []*stun.UR return } - xorAddr, err := a.udpMuxSrflx.GetXORMappedAddr(serverAddr, stunGatherTimeout) + if shouldFilterLocationTracked(serverAddr.IP) { + a.log.Warnf("STUN host %s is somehow filtered for location tracking reasons", hostPort) + return + } + + xorAddr, err := a.udpMuxSrflx.GetXORMappedAddr(serverAddr, a.stunGatherTimeout) if err != nil { a.log.Warnf("Failed get server reflexive address %s %s: %v", network, url, err) return @@ -466,6 +536,11 @@ func (a *Agent) gatherCandidatesSrflx(ctx context.Context, urls []*stun.URI, net return } + if shouldFilterLocationTracked(serverAddr.IP) { + a.log.Warnf("STUN host %s is somehow filtered for location tracking reasons", hostPort) + return + } + conn, err := listenUDPInPortRange(a.net, a.log, int(a.portMax), int(a.portMin), network, &net.UDPAddr{IP: nil, Port: 0}) if err != nil { closeConnAndLog(conn, a.log, "failed to listen for %s: %v", serverAddr.String(), err) @@ -479,12 +554,12 @@ func (a *Agent) gatherCandidatesSrflx(ctx context.Context, urls []*stun.URI, net select { case <-cancelCtx.Done(): return - case <-a.done: + case <-a.loop.Done(): _ = conn.Close() } }() - xorAddr, err := stunx.GetXORMappedAddr(conn, serverAddr, stunGatherTimeout) + xorAddr, err := stunx.GetXORMappedAddr(conn, serverAddr, a.stunGatherTimeout) if err != nil { closeConnAndLog(conn, a.log, "failed to get server reflexive address %s %s: %v", network, url, err) return @@ -605,7 +680,7 @@ func (a *Agent) gatherCandidatesRelay(ctx context.Context, urls []*stun.URI) { / return } - conn, connectErr := dtls.ClientWithContext(ctx, udpConn, &dtls.Config{ + conn, connectErr := dtls.Client(&fakenet.PacketConn{Conn: udpConn}, udpConn.RemoteAddr(), &dtls.Config{ ServerName: url.Host, InsecureSkipVerify: a.insecureSkipVerify, //nolint:gosec }) @@ -614,6 +689,11 @@ func (a *Agent) gatherCandidatesRelay(ctx context.Context, urls []*stun.URI) { / return } + if connectErr = conn.HandshakeContext(ctx); connectErr != nil { + a.log.Warnf("Failed to create DTLS client: %v", turnServerAddr, connectErr) + return + } + relAddr = conn.LocalAddr().(*net.UDPAddr).IP.String() //nolint:forcetypeassert relPort = conn.LocalAddr().(*net.UDPAddr).Port //nolint:forcetypeassert relayProtocol = relayProtocolDTLS @@ -680,6 +760,12 @@ func (a *Agent) gatherCandidatesRelay(ctx context.Context, urls []*stun.URI) { / } rAddr := relayConn.LocalAddr().(*net.UDPAddr) //nolint:forcetypeassert + + if shouldFilterLocationTracked(rAddr.IP) { + a.log.Warnf("TURN address %s is somehow filtered for location tracking reasons", rAddr.IP) + return + } + relayConfig := CandidateRelayConfig{ Network: network, Component: ComponentRTP, diff --git a/vendor/github.com/pion/ice/v2/ice.go b/vendor/github.com/pion/ice/v4/ice.go similarity index 100% rename from vendor/github.com/pion/ice/v2/ice.go rename to vendor/github.com/pion/ice/v4/ice.go diff --git a/vendor/github.com/pion/ice/v2/icecontrol.go b/vendor/github.com/pion/ice/v4/icecontrol.go similarity index 98% rename from vendor/github.com/pion/ice/v2/icecontrol.go rename to vendor/github.com/pion/ice/v4/icecontrol.go index b086bd8926..922f79a4ca 100644 --- a/vendor/github.com/pion/ice/v2/icecontrol.go +++ b/vendor/github.com/pion/ice/v4/icecontrol.go @@ -6,7 +6,7 @@ package ice import ( "encoding/binary" - "github.com/pion/stun" + "github.com/pion/stun/v3" ) // tiebreaker is common helper for ICE-{CONTROLLED,CONTROLLING} diff --git a/vendor/github.com/pion/ice/v2/internal/atomic/atomic.go b/vendor/github.com/pion/ice/v4/internal/atomic/atomic.go similarity index 100% rename from vendor/github.com/pion/ice/v2/internal/atomic/atomic.go rename to vendor/github.com/pion/ice/v4/internal/atomic/atomic.go diff --git a/vendor/github.com/pion/ice/v2/internal/fakenet/mock_conn.go b/vendor/github.com/pion/ice/v4/internal/fakenet/mock_conn.go similarity index 100% rename from vendor/github.com/pion/ice/v2/internal/fakenet/mock_conn.go rename to vendor/github.com/pion/ice/v4/internal/fakenet/mock_conn.go diff --git a/vendor/github.com/pion/ice/v2/internal/fakenet/packet_conn.go b/vendor/github.com/pion/ice/v4/internal/fakenet/packet_conn.go similarity index 100% rename from vendor/github.com/pion/ice/v2/internal/fakenet/packet_conn.go rename to vendor/github.com/pion/ice/v4/internal/fakenet/packet_conn.go diff --git a/vendor/github.com/pion/ice/v2/internal/stun/stun.go b/vendor/github.com/pion/ice/v4/internal/stun/stun.go similarity index 98% rename from vendor/github.com/pion/ice/v2/internal/stun/stun.go rename to vendor/github.com/pion/ice/v4/internal/stun/stun.go index 230cf850ad..60379ebe60 100644 --- a/vendor/github.com/pion/ice/v2/internal/stun/stun.go +++ b/vendor/github.com/pion/ice/v4/internal/stun/stun.go @@ -10,7 +10,7 @@ import ( "net" "time" - "github.com/pion/stun" + "github.com/pion/stun/v3" ) var ( diff --git a/vendor/github.com/pion/ice/v4/internal/taskloop/taskloop.go b/vendor/github.com/pion/ice/v4/internal/taskloop/taskloop.go new file mode 100644 index 0000000000..d0259983a5 --- /dev/null +++ b/vendor/github.com/pion/ice/v4/internal/taskloop/taskloop.go @@ -0,0 +1,119 @@ +// SPDX-FileCopyrightText: 2023 The Pion community +// SPDX-License-Identifier: MIT + +// Package taskloop implements a task loop to run +// tasks sequentially in a separate Goroutine. +package taskloop + +import ( + "context" + "errors" + "time" + + atomicx "github.com/pion/ice/v4/internal/atomic" +) + +// ErrClosed indicates that the loop has been stopped +var ErrClosed = errors.New("the agent is closed") + +type task struct { + fn func(context.Context) + done chan struct{} +} + +// Loop runs submitted task serially in a dedicated Goroutine +type Loop struct { + tasks chan task + + // State for closing + done chan struct{} + taskLoopDone chan struct{} + err atomicx.Error +} + +// New creates and starts a new task loop +func New(onClose func()) *Loop { + l := &Loop{ + tasks: make(chan task), + done: make(chan struct{}), + taskLoopDone: make(chan struct{}), + } + + go l.runLoop(onClose) + return l +} + +// runLoop handles registered tasks and agent close. +func (l *Loop) runLoop(onClose func()) { + defer func() { + onClose() + close(l.taskLoopDone) + }() + + for { + select { + case <-l.done: + return + case t := <-l.tasks: + t.fn(l) + close(t.done) + } + } +} + +// Close stops the loop after finishing the execution of the current task. +// Other pending tasks will not be executed. +func (l *Loop) Close() { + if err := l.Err(); err != nil { + return + } + + l.err.Store(ErrClosed) + + close(l.done) + <-l.taskLoopDone +} + +// Run serially executes the submitted callback. +// Blocking tasks must be cancelable by context. +func (l *Loop) Run(ctx context.Context, t func(context.Context)) error { + if err := l.Err(); err != nil { + return err + } + done := make(chan struct{}) + select { + case <-ctx.Done(): + return ctx.Err() + case l.tasks <- task{t, done}: + <-done + return nil + } +} + +// The following methods implement context.Context for TaskLoop + +// Done returns a channel that's closed when the task loop has been stopped. +func (l *Loop) Done() <-chan struct{} { + return l.done +} + +// Err returns nil if the task loop is still running. +// Otherwise it return errClosed if the loop has been closed/stopped. +func (l *Loop) Err() error { + select { + case <-l.done: + return ErrClosed + default: + return nil + } +} + +// Deadline returns the no valid time as task loops have no deadline. +func (l *Loop) Deadline() (deadline time.Time, ok bool) { + return time.Time{}, false +} + +// Value is not supported for task loops +func (l *Loop) Value(interface{}) interface{} { + return nil +} diff --git a/vendor/github.com/pion/ice/v4/mdns.go b/vendor/github.com/pion/ice/v4/mdns.go new file mode 100644 index 0000000000..2c10a3271c --- /dev/null +++ b/vendor/github.com/pion/ice/v4/mdns.go @@ -0,0 +1,133 @@ +// SPDX-FileCopyrightText: 2023 The Pion community +// SPDX-License-Identifier: MIT + +package ice + +import ( + "net" + + "github.com/google/uuid" + "github.com/pion/logging" + "github.com/pion/mdns/v2" + "github.com/pion/transport/v3" + "golang.org/x/net/ipv4" + "golang.org/x/net/ipv6" +) + +// MulticastDNSMode represents the different Multicast modes ICE can run in +type MulticastDNSMode byte + +// MulticastDNSMode enum +const ( + // MulticastDNSModeDisabled means remote mDNS candidates will be discarded, and local host candidates will use IPs + MulticastDNSModeDisabled MulticastDNSMode = iota + 1 + + // MulticastDNSModeQueryOnly means remote mDNS candidates will be accepted, and local host candidates will use IPs + MulticastDNSModeQueryOnly + + // MulticastDNSModeQueryAndGather means remote mDNS candidates will be accepted, and local host candidates will use mDNS + MulticastDNSModeQueryAndGather +) + +func generateMulticastDNSName() (string, error) { + // https://tools.ietf.org/id/draft-ietf-rtcweb-mdns-ice-candidates-02.html#gathering + // The unique name MUST consist of a version 4 UUID as defined in [RFC4122], followed by “.local”. + u, err := uuid.NewRandom() + return u.String() + ".local", err +} + +func createMulticastDNS( + n transport.Net, + networkTypes []NetworkType, + interfaces []*transport.Interface, + includeLoopback bool, + mDNSMode MulticastDNSMode, + mDNSName string, + log logging.LeveledLogger, +) (*mdns.Conn, MulticastDNSMode, error) { + if mDNSMode == MulticastDNSModeDisabled { + return nil, mDNSMode, nil + } + + var useV4, useV6 bool + if len(networkTypes) == 0 { + useV4 = true + useV6 = true + } else { + for _, nt := range networkTypes { + if nt.IsIPv4() { + useV4 = true + continue + } + if nt.IsIPv6() { + useV6 = true + } + } + } + + addr4, mdnsErr := n.ResolveUDPAddr("udp4", mdns.DefaultAddressIPv4) + if mdnsErr != nil { + return nil, mDNSMode, mdnsErr + } + addr6, mdnsErr := n.ResolveUDPAddr("udp6", mdns.DefaultAddressIPv6) + if mdnsErr != nil { + return nil, mDNSMode, mdnsErr + } + + var pktConnV4 *ipv4.PacketConn + var mdns4Err error + if useV4 { + var l transport.UDPConn + l, mdns4Err = n.ListenUDP("udp4", addr4) + if mdns4Err != nil { + // If ICE fails to start MulticastDNS server just warn the user and continue + log.Errorf("Failed to enable mDNS over IPv4: (%s)", mdns4Err) + return nil, MulticastDNSModeDisabled, nil + } + pktConnV4 = ipv4.NewPacketConn(l) + } + + var pktConnV6 *ipv6.PacketConn + var mdns6Err error + if useV6 { + var l transport.UDPConn + l, mdns6Err = n.ListenUDP("udp6", addr6) + if mdns6Err != nil { + log.Errorf("Failed to enable mDNS over IPv6: (%s)", mdns6Err) + return nil, MulticastDNSModeDisabled, nil + } + pktConnV6 = ipv6.NewPacketConn(l) + } + + if mdns4Err != nil && mdns6Err != nil { + // If ICE fails to start MulticastDNS server just warn the user and continue + log.Errorf("Failed to enable mDNS, continuing in mDNS disabled mode") + //nolint:nilerr + return nil, MulticastDNSModeDisabled, nil + } + var ifcs []net.Interface + if interfaces != nil { + ifcs = make([]net.Interface, 0, len(ifcs)) + for _, ifc := range interfaces { + ifcs = append(ifcs, ifc.Interface) + } + } + + switch mDNSMode { + case MulticastDNSModeQueryOnly: + conn, err := mdns.Server(pktConnV4, pktConnV6, &mdns.Config{ + Interfaces: ifcs, + IncludeLoopback: includeLoopback, + }) + return conn, mDNSMode, err + case MulticastDNSModeQueryAndGather: + conn, err := mdns.Server(pktConnV4, pktConnV6, &mdns.Config{ + Interfaces: ifcs, + IncludeLoopback: includeLoopback, + LocalNames: []string{mDNSName}, + }) + return conn, mDNSMode, err + default: + return nil, mDNSMode, nil + } +} diff --git a/vendor/github.com/pion/ice/v2/net.go b/vendor/github.com/pion/ice/v4/net.go similarity index 50% rename from vendor/github.com/pion/ice/v2/net.go rename to vendor/github.com/pion/ice/v4/net.go index d716bc19c0..6e740a70a5 100644 --- a/vendor/github.com/pion/ice/v2/net.go +++ b/vendor/github.com/pion/ice/v4/net.go @@ -5,19 +5,23 @@ package ice import ( "net" + "net/netip" "github.com/pion/logging" - "github.com/pion/transport/v2" + "github.com/pion/transport/v3" ) // The conditions of invalidation written below are defined in // https://tools.ietf.org/html/rfc8445#section-5.1.1.1 -func isSupportedIPv6(ip net.IP) bool { +// It is partial because the link-local check is done later in various gather local +// candidate methods which conditionally accept IPv6 based on usage of mDNS or not. +func isSupportedIPv6Partial(ip net.IP) bool { if len(ip) != net.IPv6len || + // Deprecated IPv4-compatible IPv6 addresses [RFC4291] and IPv6 site- + // local unicast addresses [RFC3879] MUST NOT be included in the + // address candidates. isZeros(ip[0:12]) || // !(IPv4-compatible IPv6) - ip[0] == 0xfe && ip[1]&0xc0 == 0xc0 || // !(IPv6 site-local unicast) - ip.IsLinkLocalUnicast() || - ip.IsLinkLocalMulticast() { + ip[0] == 0xfe && ip[1]&0xc0 == 0xc0 { // !(IPv6 site-local unicast) return false } return true @@ -32,21 +36,35 @@ func isZeros(ip net.IP) bool { return true } -func localInterfaces(n transport.Net, interfaceFilter func(string) bool, ipFilter func(net.IP) bool, networkTypes []NetworkType, includeLoopback bool) ([]net.IP, error) { //nolint:gocognit - ips := []net.IP{} +//nolint:gocognit +func localInterfaces( + n transport.Net, + interfaceFilter func(string) bool, + ipFilter func(net.IP) bool, + networkTypes []NetworkType, + includeLoopback bool, +) ([]*transport.Interface, []netip.Addr, error) { + ipAddrs := []netip.Addr{} ifaces, err := n.Interfaces() if err != nil { - return ips, err + return nil, ipAddrs, err } - var IPv4Requested, IPv6Requested bool - for _, typ := range networkTypes { - if typ.IsIPv4() { - IPv4Requested = true - } + filteredIfaces := make([]*transport.Interface, 0, len(ifaces)) + + var ipV4Requested, ipv6Requested bool + if len(networkTypes) == 0 { + ipV4Requested = true + ipv6Requested = true + } else { + for _, typ := range networkTypes { + if typ.IsIPv4() { + ipV4Requested = true + } - if typ.IsIPv6() { - IPv6Requested = true + if typ.IsIPv6() { + ipv6Requested = true + } } } @@ -62,41 +80,41 @@ func localInterfaces(n transport.Net, interfaceFilter func(string) bool, ipFilte continue } - addrs, err := iface.Addrs() + ifaceAddrs, err := iface.Addrs() if err != nil { continue } - for _, addr := range addrs { - var ip net.IP - switch addr := addr.(type) { - case *net.IPNet: - ip = addr.IP - case *net.IPAddr: - ip = addr.IP - } - if ip == nil || (ip.IsLoopback() && !includeLoopback) { + atLeastOneAddr := false + for _, addr := range ifaceAddrs { + ipAddr, _, _, err := parseAddrFromIface(addr, iface.Name) + if err != nil || (ipAddr.IsLoopback() && !includeLoopback) { continue } - - if ipv4 := ip.To4(); ipv4 == nil { - if !IPv6Requested { + if ipAddr.Is6() { + if !ipv6Requested { continue - } else if !isSupportedIPv6(ip) { + } else if !isSupportedIPv6Partial(ipAddr.AsSlice()) { continue } - } else if !IPv4Requested { + } else if !ipV4Requested { continue } - if ipFilter != nil && !ipFilter(ip) { + if ipFilter != nil && !ipFilter(ipAddr.AsSlice()) { continue } - ips = append(ips, ip) + atLeastOneAddr = true + ipAddrs = append(ipAddrs, ipAddr) + } + + if atLeastOneAddr { + ifaceCopy := iface + filteredIfaces = append(filteredIfaces, ifaceCopy) } } - return ips, nil + return filteredIfaces, ipAddrs, nil } func listenUDPInPortRange(n transport.Net, log logging.LeveledLogger, portMax, portMin int, network string, lAddr *net.UDPAddr) (transport.UDPConn, error) { @@ -106,7 +124,7 @@ func listenUDPInPortRange(n transport.Net, log logging.LeveledLogger, portMax, p var i, j int i = portMin if i == 0 { - i = 1 + i = 1024 // Start at 1024 which is non-privileged } j = portMax if j == 0 { diff --git a/vendor/github.com/pion/ice/v2/networktype.go b/vendor/github.com/pion/ice/v4/networktype.go similarity index 92% rename from vendor/github.com/pion/ice/v2/networktype.go rename to vendor/github.com/pion/ice/v4/networktype.go index 57df186314..376b56c741 100644 --- a/vendor/github.com/pion/ice/v2/networktype.go +++ b/vendor/github.com/pion/ice/v4/networktype.go @@ -5,7 +5,7 @@ package ice import ( "fmt" - "net" + "net/netip" "strings" ) @@ -116,18 +116,18 @@ func (t NetworkType) IsIPv6() bool { // determineNetworkType determines the type of network based on // the short network string and an IP address. -func determineNetworkType(network string, ip net.IP) (NetworkType, error) { - ipv4 := ip.To4() != nil - +func determineNetworkType(network string, ip netip.Addr) (NetworkType, error) { + // we'd rather have an IPv4-mapped IPv6 become IPv4 so that it is usable. + ip = ip.Unmap() switch { case strings.HasPrefix(strings.ToLower(network), udp): - if ipv4 { + if ip.Is4() { return NetworkTypeUDP4, nil } return NetworkTypeUDP6, nil case strings.HasPrefix(strings.ToLower(network), tcp): - if ipv4 { + if ip.Is4() { return NetworkTypeTCP4, nil } return NetworkTypeTCP6, nil diff --git a/vendor/github.com/pion/ice/v2/priority.go b/vendor/github.com/pion/ice/v4/priority.go similarity index 96% rename from vendor/github.com/pion/ice/v2/priority.go rename to vendor/github.com/pion/ice/v4/priority.go index 16ac5cc738..f49df7f434 100644 --- a/vendor/github.com/pion/ice/v2/priority.go +++ b/vendor/github.com/pion/ice/v4/priority.go @@ -6,7 +6,7 @@ package ice import ( "encoding/binary" - "github.com/pion/stun" + "github.com/pion/stun/v3" ) // PriorityAttr represents PRIORITY attribute. diff --git a/vendor/github.com/pion/ice/v2/rand.go b/vendor/github.com/pion/ice/v4/rand.go similarity index 100% rename from vendor/github.com/pion/ice/v2/rand.go rename to vendor/github.com/pion/ice/v4/rand.go diff --git a/vendor/github.com/pion/ice/v2/renovate.json b/vendor/github.com/pion/ice/v4/renovate.json similarity index 100% rename from vendor/github.com/pion/ice/v2/renovate.json rename to vendor/github.com/pion/ice/v4/renovate.json diff --git a/vendor/github.com/pion/ice/v2/role.go b/vendor/github.com/pion/ice/v4/role.go similarity index 100% rename from vendor/github.com/pion/ice/v2/role.go rename to vendor/github.com/pion/ice/v4/role.go diff --git a/vendor/github.com/pion/ice/v2/selection.go b/vendor/github.com/pion/ice/v4/selection.go similarity index 99% rename from vendor/github.com/pion/ice/v2/selection.go rename to vendor/github.com/pion/ice/v4/selection.go index 538eb0fff1..d3105301c6 100644 --- a/vendor/github.com/pion/ice/v2/selection.go +++ b/vendor/github.com/pion/ice/v4/selection.go @@ -8,7 +8,7 @@ import ( "time" "github.com/pion/logging" - "github.com/pion/stun" + "github.com/pion/stun/v3" ) type pairCandidateSelector interface { diff --git a/vendor/github.com/pion/ice/v2/stats.go b/vendor/github.com/pion/ice/v4/stats.go similarity index 100% rename from vendor/github.com/pion/ice/v2/stats.go rename to vendor/github.com/pion/ice/v4/stats.go diff --git a/vendor/github.com/pion/ice/v2/tcp_mux.go b/vendor/github.com/pion/ice/v4/tcp_mux.go similarity index 95% rename from vendor/github.com/pion/ice/v2/tcp_mux.go rename to vendor/github.com/pion/ice/v4/tcp_mux.go index ff3afed02c..ef6f038723 100644 --- a/vendor/github.com/pion/ice/v2/tcp_mux.go +++ b/vendor/github.com/pion/ice/v4/tcp_mux.go @@ -13,7 +13,7 @@ import ( "time" "github.com/pion/logging" - "github.com/pion/stun" + "github.com/pion/stun/v3" ) // ErrGetTransportAddress can't convert net.Addr to underlying type (UDPAddr or TCPAddr). @@ -142,6 +142,7 @@ func (m *TCPMuxDefault) createConn(ufrag string, isIPv6 bool, local net.IP, from return nil, ErrGetTransportAddress } localAddr := *addr + // Note: this is missing zone for IPv6 localAddr.IP = local var alive time.Duration @@ -169,13 +170,15 @@ func (m *TCPMuxDefault) createConn(ufrag string, isIPv6 bool, local net.IP, from m.connsIPv4[ufrag] = conns } } - conns[ipAddr(local.String())] = conn + // Note: this is missing zone for IPv6 + connKey := ipAddr(local.String()) + conns[connKey] = conn m.wg.Add(1) go func() { defer m.wg.Done() <-conn.CloseChannel() - m.removeConnByUfragAndLocalHost(ufrag, local) + m.removeConnByUfragAndLocalHost(ufrag, connKey) }() return conn, nil @@ -259,6 +262,7 @@ func (m *TCPMuxDefault) handleConn(conn net.Conn) { return } m.mu.Lock() + packetConn, ok := m.getConn(ufrag, isIPv6, localAddr.IP) if !ok { packetConn, err = m.createConn(ufrag, isIPv6, localAddr.IP, true) @@ -334,15 +338,14 @@ func (m *TCPMuxDefault) RemoveConnByUfrag(ufrag string) { } } -func (m *TCPMuxDefault) removeConnByUfragAndLocalHost(ufrag string, local net.IP) { +func (m *TCPMuxDefault) removeConnByUfragAndLocalHost(ufrag string, localIPAddr ipAddr) { removedConns := make([]*tcpPacketConn, 0, 4) - localIP := ipAddr(local.String()) // Keep lock section small to avoid deadlock with conn lock m.mu.Lock() if conns, ok := m.connsIPv4[ufrag]; ok { - if conn, ok := conns[localIP]; ok { - delete(conns, localIP) + if conn, ok := conns[localIPAddr]; ok { + delete(conns, localIPAddr) if len(conns) == 0 { delete(m.connsIPv4, ufrag) } @@ -350,8 +353,8 @@ func (m *TCPMuxDefault) removeConnByUfragAndLocalHost(ufrag string, local net.IP } } if conns, ok := m.connsIPv6[ufrag]; ok { - if conn, ok := conns[localIP]; ok { - delete(conns, localIP) + if conn, ok := conns[localIPAddr]; ok { + delete(conns, localIPAddr) if len(conns) == 0 { delete(m.connsIPv6, ufrag) } @@ -375,7 +378,9 @@ func (m *TCPMuxDefault) getConn(ufrag string, isIPv6 bool, local net.IP) (val *t conns, ok = m.connsIPv4[ufrag] } if conns != nil { - val, ok = conns[ipAddr(local.String())] + // Note: this is missing zone for IPv6 + connKey := ipAddr(local.String()) + val, ok = conns[connKey] } return diff --git a/vendor/github.com/pion/ice/v2/tcp_mux_multi.go b/vendor/github.com/pion/ice/v4/tcp_mux_multi.go similarity index 99% rename from vendor/github.com/pion/ice/v2/tcp_mux_multi.go rename to vendor/github.com/pion/ice/v4/tcp_mux_multi.go index e32acbf3e9..71fc570a03 100644 --- a/vendor/github.com/pion/ice/v2/tcp_mux_multi.go +++ b/vendor/github.com/pion/ice/v4/tcp_mux_multi.go @@ -3,7 +3,9 @@ package ice -import "net" +import ( + "net" +) // AllConnsGetter allows multiple fixed TCP ports to be used, // each of which is multiplexed like TCPMux. AllConnsGetter also acts as diff --git a/vendor/github.com/pion/ice/v2/tcp_packet_conn.go b/vendor/github.com/pion/ice/v4/tcp_packet_conn.go similarity index 94% rename from vendor/github.com/pion/ice/v2/tcp_packet_conn.go rename to vendor/github.com/pion/ice/v4/tcp_packet_conn.go index 60ea2c80cd..283f1da041 100644 --- a/vendor/github.com/pion/ice/v2/tcp_packet_conn.go +++ b/vendor/github.com/pion/ice/v4/tcp_packet_conn.go @@ -13,7 +13,7 @@ import ( "time" "github.com/pion/logging" - "github.com/pion/transport/v2/packetio" + "github.com/pion/transport/v3/packetio" ) type bufferedConn struct { @@ -178,8 +178,11 @@ func (t *tcpPacketConn) startReading(conn net.Conn) { n, err := readStreamingPacket(conn, buf) if err != nil { t.params.Logger.Warnf("Failed to read streaming packet: %s", err) - t.handleRecv(streamingPacket{nil, conn.RemoteAddr(), err}) - t.removeConn(conn) + last := t.removeConn(conn) + // Only propagate connection closure errors if no other open connection exists. + if last || !(errors.Is(err, io.EOF) || errors.Is(err, net.ErrClosed)) { + t.handleRecv(streamingPacket{nil, conn.RemoteAddr(), err}) + } return } @@ -262,13 +265,14 @@ func (t *tcpPacketConn) closeAndLogError(closer io.Closer) { } } -func (t *tcpPacketConn) removeConn(conn net.Conn) { +func (t *tcpPacketConn) removeConn(conn net.Conn) bool { t.mu.Lock() defer t.mu.Unlock() t.closeAndLogError(conn) delete(t.conns, conn.RemoteAddr().String()) + return len(t.conns) == 0 } func (t *tcpPacketConn) Close() error { diff --git a/vendor/github.com/pion/ice/v2/tcptype.go b/vendor/github.com/pion/ice/v4/tcptype.go similarity index 100% rename from vendor/github.com/pion/ice/v2/tcptype.go rename to vendor/github.com/pion/ice/v4/tcptype.go diff --git a/vendor/github.com/pion/ice/v2/transport.go b/vendor/github.com/pion/ice/v4/transport.go similarity index 92% rename from vendor/github.com/pion/ice/v2/transport.go rename to vendor/github.com/pion/ice/v4/transport.go index 93dc719b09..cf9e3f924e 100644 --- a/vendor/github.com/pion/ice/v2/transport.go +++ b/vendor/github.com/pion/ice/v4/transport.go @@ -9,7 +9,7 @@ import ( "sync/atomic" "time" - "github.com/pion/stun" + "github.com/pion/stun/v3" ) // Dial connects to the remote agent, acting as the controlling ice agent. @@ -43,7 +43,7 @@ func (c *Conn) BytesReceived() uint64 { } func (a *Agent) connect(ctx context.Context, isControlling bool, remoteUfrag, remotePwd string) (*Conn, error) { - err := a.ok() + err := a.loop.Err() if err != nil { return nil, err } @@ -54,8 +54,8 @@ func (a *Agent) connect(ctx context.Context, isControlling bool, remoteUfrag, re // Block until pair selected select { - case <-a.done: - return nil, a.getErr() + case <-a.loop.Done(): + return nil, a.loop.Err() case <-ctx.Done(): return nil, ErrCanceledByCaller case <-a.onConnected: @@ -68,7 +68,7 @@ func (a *Agent) connect(ctx context.Context, isControlling bool, remoteUfrag, re // Read implements the Conn Read method. func (c *Conn) Read(p []byte) (int, error) { - err := c.agent.ok() + err := c.agent.loop.Err() if err != nil { return 0, err } @@ -80,7 +80,7 @@ func (c *Conn) Read(p []byte) (int, error) { // Write implements the Conn Write method. func (c *Conn) Write(p []byte) (int, error) { - err := c.agent.ok() + err := c.agent.loop.Err() if err != nil { return 0, err } @@ -91,8 +91,8 @@ func (c *Conn) Write(p []byte) (int, error) { pair := c.agent.getSelectedPair() if pair == nil { - if err = c.agent.run(c.agent.context(), func(ctx context.Context, a *Agent) { - pair = a.getBestValidCandidatePair() + if err = c.agent.loop.Run(c.agent.loop, func(_ context.Context) { + pair = c.agent.getBestValidCandidatePair() }); err != nil { return 0, err } diff --git a/vendor/github.com/pion/ice/v2/udp_mux.go b/vendor/github.com/pion/ice/v4/udp_mux.go similarity index 82% rename from vendor/github.com/pion/ice/v2/udp_mux.go rename to vendor/github.com/pion/ice/v4/udp_mux.go index ba2a7e3809..96197b3a9e 100644 --- a/vendor/github.com/pion/ice/v2/udp_mux.go +++ b/vendor/github.com/pion/ice/v4/udp_mux.go @@ -7,14 +7,15 @@ import ( "errors" "io" "net" + "net/netip" "os" "strings" "sync" "github.com/pion/logging" - "github.com/pion/stun" - "github.com/pion/transport/v2" - "github.com/pion/transport/v2/stdnet" + "github.com/pion/stun/v3" + "github.com/pion/transport/v3" + "github.com/pion/transport/v3/stdnet" ) // UDPMux allows multiple connections to go over a single UDP port @@ -36,7 +37,7 @@ type UDPMuxDefault struct { connsIPv4, connsIPv6 map[string]*udpMuxedConn addressMapMu sync.RWMutex - addressMap map[udpMuxedConnAddr]*udpMuxedConn + addressMap map[ipPort]*udpMuxedConn // Buffer pool to recycle buffers for net.UDPAddr encodes/decodes pool *sync.Pool @@ -49,8 +50,9 @@ type UDPMuxDefault struct { // UDPMuxParams are parameters for UDPMux. type UDPMuxParams struct { - Logger logging.LeveledLogger - UDPConn net.PacketConn + Logger logging.LeveledLogger + UDPConn net.PacketConn + UDPConnString string // Required for gathering local addresses // in case a un UDPConn is passed which does not @@ -65,19 +67,19 @@ func NewUDPMuxDefault(params UDPMuxParams) *UDPMuxDefault { } var localAddrsForUnspecified []net.Addr - if addr, ok := params.UDPConn.LocalAddr().(*net.UDPAddr); !ok { + if udpAddr, ok := params.UDPConn.LocalAddr().(*net.UDPAddr); !ok { params.Logger.Errorf("LocalAddr is not a net.UDPAddr, got %T", params.UDPConn.LocalAddr()) - } else if ok && addr.IP.IsUnspecified() { + } else if ok && udpAddr.IP.IsUnspecified() { // For unspecified addresses, the correct behavior is to return errListenUnspecified, but // it will break the applications that are already using unspecified UDP connection // with UDPMuxDefault, so print a warn log and create a local address list for mux. params.Logger.Warn("UDPMuxDefault should not listening on unspecified address, use NewMultiUDPMuxFromPort instead") var networks []NetworkType switch { - case addr.IP.To4() != nil: + case udpAddr.IP.To4() != nil: networks = []NetworkType{NetworkTypeUDP4} - case addr.IP.To16() != nil: + case udpAddr.IP.To16() != nil: networks = []NetworkType{NetworkTypeUDP4, NetworkTypeUDP6} default: @@ -91,19 +93,24 @@ func NewUDPMuxDefault(params UDPMuxParams) *UDPMuxDefault { } } - ips, err := localInterfaces(params.Net, nil, nil, networks, true) + _, addrs, err := localInterfaces(params.Net, nil, nil, networks, true) if err == nil { - for _, ip := range ips { - localAddrsForUnspecified = append(localAddrsForUnspecified, &net.UDPAddr{IP: ip, Port: addr.Port}) + for _, addr := range addrs { + localAddrsForUnspecified = append(localAddrsForUnspecified, &net.UDPAddr{ + IP: addr.AsSlice(), + Port: udpAddr.Port, + Zone: addr.Zone(), + }) } } else { params.Logger.Errorf("Failed to get local interfaces for unspecified addr: %v", err) } } } + params.UDPConnString = params.UDPConn.LocalAddr().String() m := &UDPMuxDefault{ - addressMap: map[udpMuxedConnAddr]*udpMuxedConn{}, + addressMap: map[ipPort]*udpMuxedConn{}, params: params, connsIPv4: make(map[string]*udpMuxedConn), connsIPv6: make(map[string]*udpMuxedConn), @@ -140,7 +147,7 @@ func (m *UDPMuxDefault) GetListenAddresses() []net.Addr { // creates the connection if an existing one can't be found func (m *UDPMuxDefault) GetConn(ufrag string, addr net.Addr) (net.PacketConn, error) { // don't check addr for mux using unspecified address - if len(m.localAddrsForUnspecified) == 0 && m.params.UDPConn.LocalAddr().String() != addr.String() { + if len(m.localAddrsForUnspecified) == 0 && m.params.UDPConnString != addr.String() { return nil, errInvalidAddress } @@ -244,7 +251,7 @@ func (m *UDPMuxDefault) writeTo(buf []byte, rAddr net.Addr) (n int, err error) { return m.params.UDPConn.WriteTo(buf, rAddr) } -func (m *UDPMuxDefault) registerConnForAddress(conn *udpMuxedConn, addr udpMuxedConnAddr) { +func (m *UDPMuxDefault) registerConnForAddress(conn *udpMuxedConn, addr ipPort) { if m.IsClosed() { return } @@ -258,7 +265,7 @@ func (m *UDPMuxDefault) registerConnForAddress(conn *udpMuxedConn, addr udpMuxed } m.addressMap[addr] = conn - m.params.Logger.Debugf("Registered %s for %s", addr, conn.params.Key) + m.params.Logger.Debugf("Registered %s for %s", addr.addr.String(), conn.params.Key) } func (m *UDPMuxDefault) createMuxedConn(key string) *udpMuxedConn { @@ -294,15 +301,20 @@ func (m *UDPMuxDefault) connWorker() { return } - udpAddr, ok := addr.(*net.UDPAddr) + netUDPAddr, ok := addr.(*net.UDPAddr) if !ok { logger.Errorf("Underlying PacketConn did not return a UDPAddr") return } + udpAddr, err := newIPPort(netUDPAddr.IP, netUDPAddr.Zone, uint16(netUDPAddr.Port)) + if err != nil { + logger.Errorf("Failed to create a new IP/Port host pair") + return + } // If we have already seen this address dispatch to the appropriate destination m.addressMapMu.Lock() - destinationConn := m.addressMap[newUDPMuxedConnAddr(udpAddr)] + destinationConn := m.addressMap[udpAddr] m.addressMapMu.Unlock() // If we haven't seen this address before but is a STUN packet lookup by ufrag @@ -323,7 +335,7 @@ func (m *UDPMuxDefault) connWorker() { } ufrag := strings.Split(string(attr), ":")[0] - isIPv6 := udpAddr.IP.To4() == nil + isIPv6 := netUDPAddr.IP.To4() == nil m.mu.Lock() destinationConn, _ = m.getConn(ufrag, isIPv6) @@ -331,11 +343,11 @@ func (m *UDPMuxDefault) connWorker() { } if destinationConn == nil { - m.params.Logger.Tracef("Dropping packet from %s, addr: %s", udpAddr, addr) + m.params.Logger.Tracef("Dropping packet from %s, addr: %s", udpAddr.addr, addr) continue } - if err = destinationConn.writePacket(buf[:n], udpAddr); err != nil { + if err = destinationConn.writePacket(buf[:n], netUDPAddr); err != nil { m.params.Logger.Errorf("Failed to write packet: %v", err) } } @@ -366,3 +378,23 @@ func (b *bufferHolder) reset() { b.next = nil b.addr = nil } + +type ipPort struct { + addr netip.Addr + port uint16 +} + +// newIPPort create a custom type of address based on netip.Addr and +// port. The underlying ip address passed is converted to IPv6 format +// to simplify ip address handling +func newIPPort(ip net.IP, zone string, port uint16) (ipPort, error) { + n, ok := netip.AddrFromSlice(ip.To16()) + if !ok { + return ipPort{}, errInvalidIPAddress + } + + return ipPort{ + addr: n.WithZone(zone), + port: port, + }, nil +} diff --git a/vendor/github.com/pion/ice/v2/udp_mux_multi.go b/vendor/github.com/pion/ice/v4/udp_mux_multi.go similarity index 93% rename from vendor/github.com/pion/ice/v2/udp_mux_multi.go rename to vendor/github.com/pion/ice/v4/udp_mux_multi.go index 158cbc37fe..2594cb0205 100644 --- a/vendor/github.com/pion/ice/v2/udp_mux_multi.go +++ b/vendor/github.com/pion/ice/v4/udp_mux_multi.go @@ -8,8 +8,8 @@ import ( "net" "github.com/pion/logging" - "github.com/pion/transport/v2" - "github.com/pion/transport/v2/stdnet" + "github.com/pion/transport/v3" + "github.com/pion/transport/v3/stdnet" ) // MultiUDPMuxDefault implements both UDPMux and AllConnsGetter, @@ -90,14 +90,18 @@ func NewMultiUDPMuxFromPort(port int, opts ...UDPMuxFromPortOption) (*MultiUDPMu } } - ips, err := localInterfaces(params.net, params.ifFilter, params.ipFilter, params.networks, params.includeLoopback) + _, addrs, err := localInterfaces(params.net, params.ifFilter, params.ipFilter, params.networks, params.includeLoopback) if err != nil { return nil, err } - conns := make([]net.PacketConn, 0, len(ips)) - for _, ip := range ips { - conn, listenErr := params.net.ListenUDP("udp", &net.UDPAddr{IP: ip, Port: port}) + conns := make([]net.PacketConn, 0, len(addrs)) + for _, addr := range addrs { + conn, listenErr := params.net.ListenUDP("udp", &net.UDPAddr{ + IP: addr.AsSlice(), + Port: port, + Zone: addr.Zone(), + }) if listenErr != nil { err = listenErr break diff --git a/vendor/github.com/pion/ice/v2/udp_mux_universal.go b/vendor/github.com/pion/ice/v4/udp_mux_universal.go similarity index 99% rename from vendor/github.com/pion/ice/v2/udp_mux_universal.go rename to vendor/github.com/pion/ice/v4/udp_mux_universal.go index 0a648af3ea..79c12fbc5d 100644 --- a/vendor/github.com/pion/ice/v2/udp_mux_universal.go +++ b/vendor/github.com/pion/ice/v4/udp_mux_universal.go @@ -9,8 +9,8 @@ import ( "time" "github.com/pion/logging" - "github.com/pion/stun" - "github.com/pion/transport/v2" + "github.com/pion/stun/v3" + "github.com/pion/transport/v3" ) // UniversalUDPMux allows multiple connections to go over a single UDP port for diff --git a/vendor/github.com/pion/ice/v2/udp_muxed_conn.go b/vendor/github.com/pion/ice/v4/udp_muxed_conn.go similarity index 85% rename from vendor/github.com/pion/ice/v2/udp_muxed_conn.go rename to vendor/github.com/pion/ice/v4/udp_muxed_conn.go index 322d02074a..9f438b3e0c 100644 --- a/vendor/github.com/pion/ice/v2/udp_muxed_conn.go +++ b/vendor/github.com/pion/ice/v4/udp_muxed_conn.go @@ -20,17 +20,6 @@ const ( udpMuxedConnClosed ) -type udpMuxedConnAddr struct { - ip [16]byte - port uint16 -} - -func newUDPMuxedConnAddr(addr *net.UDPAddr) (a udpMuxedConnAddr) { - copy(a.ip[:], addr.IP.To16()) - a.port = uint16(addr.Port) - return a -} - type udpMuxedConnParams struct { Mux *UDPMuxDefault AddrPool *sync.Pool @@ -43,7 +32,7 @@ type udpMuxedConnParams struct { type udpMuxedConn struct { params *udpMuxedConnParams // Remote addresses that we have sent to on this conn - addresses []udpMuxedConnAddr + addresses []ipPort // FIFO queue holding incoming packets bufHead, bufTail *bufferHolder @@ -107,9 +96,17 @@ func (c *udpMuxedConn) WriteTo(buf []byte, rAddr net.Addr) (n int, err error) { return 0, io.ErrClosedPipe } // Each time we write to a new address, we'll register it with the mux - addr := newUDPMuxedConnAddr(rAddr.(*net.UDPAddr)) - if !c.containsAddress(addr) { - c.addAddress(addr) + netUDPAddr, ok := rAddr.(*net.UDPAddr) + if !ok { + return 0, errFailedToCastUDPAddr + } + + ipAndPort, err := newIPPort(netUDPAddr.IP, netUDPAddr.Zone, uint16(netUDPAddr.Port)) + if err != nil { + return 0, err + } + if !c.containsAddress(ipAndPort) { + c.addAddress(ipAndPort) } return c.params.Mux.writeTo(buf, rAddr) @@ -162,15 +159,15 @@ func (c *udpMuxedConn) isClosed() bool { return c.state == udpMuxedConnClosed } -func (c *udpMuxedConn) getAddresses() []udpMuxedConnAddr { +func (c *udpMuxedConn) getAddresses() []ipPort { c.mu.Lock() defer c.mu.Unlock() - addresses := make([]udpMuxedConnAddr, len(c.addresses)) + addresses := make([]ipPort, len(c.addresses)) copy(addresses, c.addresses) return addresses } -func (c *udpMuxedConn) addAddress(addr udpMuxedConnAddr) { +func (c *udpMuxedConn) addAddress(addr ipPort) { c.mu.Lock() c.addresses = append(c.addresses, addr) c.mu.Unlock() @@ -179,11 +176,11 @@ func (c *udpMuxedConn) addAddress(addr udpMuxedConnAddr) { c.params.Mux.registerConnForAddress(c, addr) } -func (c *udpMuxedConn) removeAddress(addr udpMuxedConnAddr) { +func (c *udpMuxedConn) removeAddress(addr ipPort) { c.mu.Lock() defer c.mu.Unlock() - newAddresses := make([]udpMuxedConnAddr, 0, len(c.addresses)) + newAddresses := make([]ipPort, 0, len(c.addresses)) for _, a := range c.addresses { if a != addr { newAddresses = append(newAddresses, a) @@ -193,7 +190,7 @@ func (c *udpMuxedConn) removeAddress(addr udpMuxedConnAddr) { c.addresses = newAddresses } -func (c *udpMuxedConn) containsAddress(addr udpMuxedConnAddr) bool { +func (c *udpMuxedConn) containsAddress(addr ipPort) bool { c.mu.Lock() defer c.mu.Unlock() for _, a := range c.addresses { diff --git a/vendor/github.com/pion/ice/v2/url.go b/vendor/github.com/pion/ice/v4/url.go similarity index 98% rename from vendor/github.com/pion/ice/v2/url.go rename to vendor/github.com/pion/ice/v4/url.go index b2b9f8bd39..29338bfd5b 100644 --- a/vendor/github.com/pion/ice/v2/url.go +++ b/vendor/github.com/pion/ice/v4/url.go @@ -3,7 +3,7 @@ package ice -import "github.com/pion/stun" +import "github.com/pion/stun/v3" type ( // URL represents a STUN (rfc7064) or TURN (rfc7065) URI diff --git a/vendor/github.com/pion/ice/v2/usecandidate.go b/vendor/github.com/pion/ice/v4/usecandidate.go similarity index 95% rename from vendor/github.com/pion/ice/v2/usecandidate.go rename to vendor/github.com/pion/ice/v4/usecandidate.go index 6fc7ed50c5..ea03bb8b2d 100644 --- a/vendor/github.com/pion/ice/v2/usecandidate.go +++ b/vendor/github.com/pion/ice/v4/usecandidate.go @@ -3,7 +3,7 @@ package ice -import "github.com/pion/stun" +import "github.com/pion/stun/v3" // UseCandidateAttr represents USE-CANDIDATE attribute. type UseCandidateAttr struct{} diff --git a/vendor/github.com/pion/interceptor/pkg/rfc8888/interceptor.go b/vendor/github.com/pion/interceptor/pkg/rfc8888/interceptor.go new file mode 100644 index 0000000000..efe2df29c3 --- /dev/null +++ b/vendor/github.com/pion/interceptor/pkg/rfc8888/interceptor.go @@ -0,0 +1,182 @@ +// SPDX-FileCopyrightText: 2023 The Pion community +// SPDX-License-Identifier: MIT + +// Package rfc8888 provides an interceptor that generates congestion control +// feedback reports as defined by RFC 8888. +package rfc8888 + +import ( + "sync" + "time" + + "github.com/pion/interceptor" + "github.com/pion/logging" + "github.com/pion/rtcp" +) + +// TickerFactory is a factory to create new tickers +type TickerFactory func(d time.Duration) ticker + +// SenderInterceptorFactory is a interceptor.Factory for a SenderInterceptor +type SenderInterceptorFactory struct { + opts []Option +} + +// NewInterceptor constructs a new SenderInterceptor +func (s *SenderInterceptorFactory) NewInterceptor(_ string) (interceptor.Interceptor, error) { + i := &SenderInterceptor{ + NoOp: interceptor.NoOp{}, + log: logging.NewDefaultLoggerFactory().NewLogger("rfc8888_interceptor"), + lock: sync.Mutex{}, + wg: sync.WaitGroup{}, + recorder: NewRecorder(), + interval: 100 * time.Millisecond, + maxReportSize: 1200, + packetChan: make(chan packet), + newTicker: func(d time.Duration) ticker { + return &timeTicker{time.NewTicker(d)} + }, + now: time.Now, + close: make(chan struct{}), + } + for _, opt := range s.opts { + err := opt(i) + if err != nil { + return nil, err + } + } + return i, nil +} + +// NewSenderInterceptor returns a new SenderInterceptorFactory configured with the given options. +func NewSenderInterceptor(opts ...Option) (*SenderInterceptorFactory, error) { + return &SenderInterceptorFactory{opts: opts}, nil +} + +// SenderInterceptor sends congestion control feedback as specified in RFC 8888. +type SenderInterceptor struct { + interceptor.NoOp + log logging.LeveledLogger + lock sync.Mutex + wg sync.WaitGroup + recorder *Recorder + interval time.Duration + maxReportSize int64 + packetChan chan packet + newTicker TickerFactory + now func() time.Time + close chan struct{} +} + +type packet struct { + arrival time.Time + ssrc uint32 + sequenceNumber uint16 + ecn uint8 +} + +// BindRTCPWriter lets you modify any outgoing RTCP packets. It is called once per PeerConnection. The returned method +// will be called once per packet batch. +func (s *SenderInterceptor) BindRTCPWriter(writer interceptor.RTCPWriter) interceptor.RTCPWriter { + s.lock.Lock() + defer s.lock.Unlock() + + if s.isClosed() { + return writer + } + + s.wg.Add(1) + go s.loop(writer) + + return writer +} + +// BindRemoteStream lets you modify any incoming RTP packets. It is called once for per RemoteStream. The returned method +// will be called once per rtp packet. +func (s *SenderInterceptor) BindRemoteStream(_ *interceptor.StreamInfo, reader interceptor.RTPReader) interceptor.RTPReader { + return interceptor.RTPReaderFunc(func(b []byte, a interceptor.Attributes) (int, interceptor.Attributes, error) { + i, attr, err := reader.Read(b, a) + if err != nil { + return 0, nil, err + } + + if attr == nil { + attr = make(interceptor.Attributes) + } + header, err := attr.GetRTPHeader(b[:i]) + if err != nil { + return 0, nil, err + } + + p := packet{ + arrival: s.now(), + ssrc: header.SSRC, + sequenceNumber: header.SequenceNumber, + ecn: 0, // ECN is not supported (yet). + } + s.packetChan <- p + return i, attr, nil + }) +} + +// Close closes the interceptor. +func (s *SenderInterceptor) Close() error { + s.log.Trace("close") + defer s.wg.Wait() + + if !s.isClosed() { + close(s.close) + } + + return nil +} + +func (s *SenderInterceptor) isClosed() bool { + select { + case <-s.close: + return true + default: + return false + } +} + +func (s *SenderInterceptor) loop(writer interceptor.RTCPWriter) { + defer s.wg.Done() + + select { + case <-s.close: + return + case pkt := <-s.packetChan: + s.log.Tracef("got first packet: %v", pkt) + s.recorder.AddPacket(pkt.arrival, pkt.ssrc, pkt.sequenceNumber, pkt.ecn) + } + + s.log.Trace("start loop") + t := s.newTicker(s.interval) + for { + select { + case <-s.close: + t.Stop() + return + + case pkt := <-s.packetChan: + s.log.Tracef("got packet: %v", pkt) + s.recorder.AddPacket(pkt.arrival, pkt.ssrc, pkt.sequenceNumber, pkt.ecn) + + case now := <-t.Ch(): + s.log.Tracef("report triggered at %v", now) + if writer == nil { + s.log.Trace("no writer added, continue") + continue + } + pkts := s.recorder.BuildReport(now, int(s.maxReportSize)) + if pkts == nil { + continue + } + s.log.Tracef("got report: %v", pkts) + if _, err := writer.Write([]rtcp.Packet{pkts}, nil); err != nil { + s.log.Error(err.Error()) + } + } + } +} diff --git a/vendor/github.com/pion/interceptor/pkg/rfc8888/option.go b/vendor/github.com/pion/interceptor/pkg/rfc8888/option.go new file mode 100644 index 0000000000..1214868bf3 --- /dev/null +++ b/vendor/github.com/pion/interceptor/pkg/rfc8888/option.go @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: 2023 The Pion community +// SPDX-License-Identifier: MIT + +package rfc8888 + +import "time" + +// An Option is a function that can be used to configure a SenderInterceptor +type Option func(*SenderInterceptor) error + +// SenderTicker sets an alternative for time.Ticker. +func SenderTicker(f TickerFactory) Option { + return func(i *SenderInterceptor) error { + i.newTicker = f + return nil + } +} + +// SenderNow sets an alternative for the time.Now function. +func SenderNow(f func() time.Time) Option { + return func(i *SenderInterceptor) error { + i.now = f + return nil + } +} + +// SendInterval sets the feedback send interval for the interceptor +func SendInterval(interval time.Duration) Option { + return func(s *SenderInterceptor) error { + s.interval = interval + return nil + } +} diff --git a/vendor/github.com/pion/interceptor/pkg/rfc8888/recorder.go b/vendor/github.com/pion/interceptor/pkg/rfc8888/recorder.go new file mode 100644 index 0000000000..4423df1e30 --- /dev/null +++ b/vendor/github.com/pion/interceptor/pkg/rfc8888/recorder.go @@ -0,0 +1,78 @@ +// SPDX-FileCopyrightText: 2023 The Pion community +// SPDX-License-Identifier: MIT + +package rfc8888 + +import ( + "time" + + "github.com/pion/rtcp" +) + +type packetReport struct { + arrivalTime time.Time + ecn uint8 +} + +// Recorder records incoming RTP packets and their arrival times. Recorder can +// be used to create feedback reports as defined by RFC 8888. +type Recorder struct { + ssrc uint32 + streams map[uint32]*streamLog +} + +// NewRecorder creates a new Recorder +func NewRecorder() *Recorder { + return &Recorder{ + streams: map[uint32]*streamLog{}, + } +} + +// AddPacket writes a packet to the underlying stream. +func (r *Recorder) AddPacket(ts time.Time, ssrc uint32, seq uint16, ecn uint8) { + stream, ok := r.streams[ssrc] + if !ok { + stream = newStreamLog(ssrc) + r.streams[ssrc] = stream + } + stream.add(ts, seq, ecn) +} + +// BuildReport creates a new rtcp.CCFeedbackReport containing all packets that +// were added by AddPacket and missing packets. +func (r *Recorder) BuildReport(now time.Time, maxSize int) *rtcp.CCFeedbackReport { + report := &rtcp.CCFeedbackReport{ + SenderSSRC: r.ssrc, + ReportBlocks: []rtcp.CCFeedbackReportBlock{}, + ReportTimestamp: ntpTime32(now), + } + + maxReportBlocks := (maxSize - 12 - (8 * len(r.streams))) / 2 + var maxReportBlocksPerStream int + if len(r.streams) > 1 { + maxReportBlocksPerStream = maxReportBlocks / (len(r.streams) - 1) + } else { + maxReportBlocksPerStream = maxReportBlocks + } + + for i, log := range r.streams { + if len(r.streams) > 1 && int(i) == len(r.streams)-1 { + maxReportBlocksPerStream = maxReportBlocks % len(r.streams) + } + block := log.metricsAfter(now, int64(maxReportBlocksPerStream)) + report.ReportBlocks = append(report.ReportBlocks, block) + } + + return report +} + +func ntpTime32(t time.Time) uint32 { + // seconds since 1st January 1900 + s := (float64(t.UnixNano()) / 1000000000.0) + 2208988800 + + integerPart := uint32(s) + fractionalPart := uint32((s - float64(integerPart)) * 0xFFFFFFFF) + + // higher 32 bits are the integer part, lower 32 bits are the fractional part + return uint32(((uint64(integerPart)<<32 | uint64(fractionalPart)) >> 16) & 0xFFFFFFFF) +} diff --git a/vendor/github.com/pion/interceptor/pkg/rfc8888/stream_log.go b/vendor/github.com/pion/interceptor/pkg/rfc8888/stream_log.go new file mode 100644 index 0000000000..8dfb14fc96 --- /dev/null +++ b/vendor/github.com/pion/interceptor/pkg/rfc8888/stream_log.go @@ -0,0 +1,110 @@ +// SPDX-FileCopyrightText: 2023 The Pion community +// SPDX-License-Identifier: MIT + +package rfc8888 + +import ( + "time" + + "github.com/pion/rtcp" +) + +const maxReportsPerReportBlock = 16384 + +type streamLog struct { + ssrc uint32 + sequence unwrapper + init bool + nextSequenceNumberToReport int64 // next to report + lastSequenceNumberReceived int64 // highest received + log map[int64]*packetReport +} + +func newStreamLog(ssrc uint32) *streamLog { + return &streamLog{ + ssrc: ssrc, + sequence: unwrapper{}, + init: false, + nextSequenceNumberToReport: 0, + lastSequenceNumberReceived: 0, + log: map[int64]*packetReport{}, + } +} + +func (l *streamLog) add(ts time.Time, sequenceNumber uint16, ecn uint8) { + unwrappedSequenceNumber := l.sequence.unwrap(sequenceNumber) + if !l.init { + l.init = true + l.nextSequenceNumberToReport = unwrappedSequenceNumber + } + l.log[unwrappedSequenceNumber] = &packetReport{ + arrivalTime: ts, + ecn: ecn, + } + if l.lastSequenceNumberReceived < unwrappedSequenceNumber { + l.lastSequenceNumberReceived = unwrappedSequenceNumber + } +} + +// metricsAfter iterates over all packets order of their sequence number. +// Packets are removed until the first loss is detected. +func (l *streamLog) metricsAfter(reference time.Time, maxReportBlocks int64) rtcp.CCFeedbackReportBlock { + if len(l.log) == 0 { + return rtcp.CCFeedbackReportBlock{ + MediaSSRC: l.ssrc, + BeginSequence: uint16(l.nextSequenceNumberToReport), + MetricBlocks: []rtcp.CCFeedbackMetricBlock{}, + } + } + numReports := l.lastSequenceNumberReceived - l.nextSequenceNumberToReport + 1 + if numReports > maxReportBlocks { + numReports = maxReportBlocks + l.nextSequenceNumberToReport = l.lastSequenceNumberReceived - maxReportBlocks + 1 + } + metricBlocks := make([]rtcp.CCFeedbackMetricBlock, numReports) + offset := l.nextSequenceNumberToReport + lastReceived := l.nextSequenceNumberToReport + gapDetected := false + for i := offset; i <= l.lastSequenceNumberReceived; i++ { + received := false + ecn := uint8(0) + ato := uint16(0) + if report, ok := l.log[i]; ok { + received = true + ecn = report.ecn + ato = getArrivalTimeOffset(reference, report.arrivalTime) + } + metricBlocks[i-offset] = rtcp.CCFeedbackMetricBlock{ + Received: received, + ECN: rtcp.ECN(ecn), + ArrivalTimeOffset: ato, + } + + if !gapDetected { + if received && i == l.nextSequenceNumberToReport { + delete(l.log, i) + l.nextSequenceNumberToReport++ + lastReceived = i + } + if i > lastReceived+1 { + gapDetected = true + } + } + } + return rtcp.CCFeedbackReportBlock{ + MediaSSRC: l.ssrc, + BeginSequence: uint16(offset), + MetricBlocks: metricBlocks, + } +} + +func getArrivalTimeOffset(base time.Time, arrival time.Time) uint16 { + if base.Before(arrival) { + return 0x1FFF + } + ato := uint16(base.Sub(arrival).Seconds() * 1024.0) + if ato > 0x1FFD { + return 0x1FFE + } + return ato +} diff --git a/vendor/github.com/pion/interceptor/pkg/rfc8888/ticker.go b/vendor/github.com/pion/interceptor/pkg/rfc8888/ticker.go new file mode 100644 index 0000000000..571b28e0bf --- /dev/null +++ b/vendor/github.com/pion/interceptor/pkg/rfc8888/ticker.go @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: 2023 The Pion community +// SPDX-License-Identifier: MIT + +package rfc8888 + +import "time" + +type ticker interface { + Ch() <-chan time.Time + Stop() +} + +type timeTicker struct { + *time.Ticker +} + +func (t *timeTicker) Ch() <-chan time.Time { + return t.C +} diff --git a/vendor/github.com/pion/interceptor/pkg/rfc8888/unwrapper.go b/vendor/github.com/pion/interceptor/pkg/rfc8888/unwrapper.go new file mode 100644 index 0000000000..f15f33e6ef --- /dev/null +++ b/vendor/github.com/pion/interceptor/pkg/rfc8888/unwrapper.go @@ -0,0 +1,42 @@ +// SPDX-FileCopyrightText: 2023 The Pion community +// SPDX-License-Identifier: MIT + +package rfc8888 + +const ( + maxSequenceNumberPlusOne = int64(65536) + breakpoint = 32768 // half of max uint16 +) + +type unwrapper struct { + init bool + lastUnwrapped int64 +} + +func isNewer(value, previous uint16) bool { + if value-previous == breakpoint { + return value > previous + } + return value != previous && (value-previous) < breakpoint +} + +func (u *unwrapper) unwrap(i uint16) int64 { + if !u.init { + u.init = true + u.lastUnwrapped = int64(i) + return u.lastUnwrapped + } + + lastWrapped := uint16(u.lastUnwrapped) + delta := int64(i - lastWrapped) + if isNewer(i, lastWrapped) { + if delta < 0 { + delta += maxSequenceNumberPlusOne + } + } else if delta > 0 && u.lastUnwrapped+delta-maxSequenceNumberPlusOne >= 0 { + delta -= maxSequenceNumberPlusOne + } + + u.lastUnwrapped += delta + return u.lastUnwrapped +} diff --git a/vendor/github.com/pion/mdns/conn.go b/vendor/github.com/pion/mdns/conn.go deleted file mode 100644 index 1f146072ba..0000000000 --- a/vendor/github.com/pion/mdns/conn.go +++ /dev/null @@ -1,597 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package mdns - -import ( - "context" - "errors" - "fmt" - "net" - "sync" - "time" - - "github.com/pion/logging" - "golang.org/x/net/dns/dnsmessage" - "golang.org/x/net/ipv4" -) - -// Conn represents a mDNS Server -type Conn struct { - mu sync.RWMutex - log logging.LeveledLogger - - socket *ipv4.PacketConn - dstAddr *net.UDPAddr - - queryInterval time.Duration - localNames []string - queries []*query - ifaces []net.Interface - - closed chan interface{} -} - -type query struct { - nameWithSuffix string - queryResultChan chan queryResult -} - -type queryResult struct { - answer dnsmessage.ResourceHeader - addr net.Addr -} - -const ( - defaultQueryInterval = time.Second - destinationAddress = "224.0.0.251:5353" - maxMessageRecords = 3 - responseTTL = 120 - // maxPacketSize is the maximum size of a mdns packet. - // From RFC 6762: - // Even when fragmentation is used, a Multicast DNS packet, including IP - // and UDP headers, MUST NOT exceed 9000 bytes. - // https://datatracker.ietf.org/doc/html/rfc6762#section-17 - maxPacketSize = 9000 -) - -var errNoPositiveMTUFound = errors.New("no positive MTU found") - -// Server establishes a mDNS connection over an existing conn. -// -// Currently, the server only supports listening on an IPv4 connection, but internally -// it supports answering with IPv6 AAAA records if this were ever to change. -func Server(conn *ipv4.PacketConn, config *Config) (*Conn, error) { - if config == nil { - return nil, errNilConfig - } - - ifaces := config.Interfaces - if ifaces == nil { - var err error - ifaces, err = net.Interfaces() - if err != nil { - return nil, err - } - } - - inboundBufferSize := 0 - joinErrCount := 0 - ifacesToUse := make([]net.Interface, 0, len(ifaces)) - for i, ifc := range ifaces { - if !config.IncludeLoopback && ifc.Flags&net.FlagLoopback == net.FlagLoopback { - continue - } - if err := conn.JoinGroup(&ifaces[i], &net.UDPAddr{IP: net.IPv4(224, 0, 0, 251)}); err != nil { - joinErrCount++ - continue - } - - ifcCopy := ifc - ifacesToUse = append(ifacesToUse, ifcCopy) - if ifaces[i].MTU > inboundBufferSize { - inboundBufferSize = ifaces[i].MTU - } - } - - if inboundBufferSize == 0 { - return nil, errNoPositiveMTUFound - } - if inboundBufferSize > maxPacketSize { - inboundBufferSize = maxPacketSize - } - if joinErrCount >= len(ifaces) { - return nil, errJoiningMulticastGroup - } - - dstAddr, err := net.ResolveUDPAddr("udp", destinationAddress) - if err != nil { - return nil, err - } - - loggerFactory := config.LoggerFactory - if loggerFactory == nil { - loggerFactory = logging.NewDefaultLoggerFactory() - } - - localNames := []string{} - for _, l := range config.LocalNames { - localNames = append(localNames, l+".") - } - - c := &Conn{ - queryInterval: defaultQueryInterval, - queries: []*query{}, - socket: conn, - dstAddr: dstAddr, - localNames: localNames, - ifaces: ifacesToUse, - log: loggerFactory.NewLogger("mdns"), - closed: make(chan interface{}), - } - if config.QueryInterval != 0 { - c.queryInterval = config.QueryInterval - } - - if err := conn.SetControlMessage(ipv4.FlagInterface, true); err != nil { - c.log.Warnf("Failed to SetControlMessage on PacketConn %v", err) - } - - if config.IncludeLoopback { - // this is an efficient way for us to send ourselves a message faster instead of it going - // further out into the network stack. - if err := conn.SetMulticastLoopback(true); err != nil { - c.log.Warnf("Failed to SetMulticastLoopback(true) on PacketConn %v; this may cause inefficient network path communications", err) - } - } - - // https://www.rfc-editor.org/rfc/rfc6762.html#section-17 - // Multicast DNS messages carried by UDP may be up to the IP MTU of the - // physical interface, less the space required for the IP header (20 - // bytes for IPv4; 40 bytes for IPv6) and the UDP header (8 bytes). - go c.start(inboundBufferSize-20-8, config) - return c, nil -} - -// Close closes the mDNS Conn -func (c *Conn) Close() error { - select { - case <-c.closed: - return nil - default: - } - - if err := c.socket.Close(); err != nil { - return err - } - - <-c.closed - return nil -} - -// Query sends mDNS Queries for the following name until -// either the Context is canceled/expires or we get a result -func (c *Conn) Query(ctx context.Context, name string) (dnsmessage.ResourceHeader, net.Addr, error) { - select { - case <-c.closed: - return dnsmessage.ResourceHeader{}, nil, errConnectionClosed - default: - } - - nameWithSuffix := name + "." - - queryChan := make(chan queryResult, 1) - query := &query{nameWithSuffix, queryChan} - c.mu.Lock() - c.queries = append(c.queries, query) - c.mu.Unlock() - - defer func() { - c.mu.Lock() - defer c.mu.Unlock() - for i := len(c.queries) - 1; i >= 0; i-- { - if c.queries[i] == query { - c.queries = append(c.queries[:i], c.queries[i+1:]...) - } - } - }() - - ticker := time.NewTicker(c.queryInterval) - defer ticker.Stop() - - c.sendQuestion(nameWithSuffix) - for { - select { - case <-ticker.C: - c.sendQuestion(nameWithSuffix) - case <-c.closed: - return dnsmessage.ResourceHeader{}, nil, errConnectionClosed - case res := <-queryChan: - // Given https://datatracker.ietf.org/doc/html/draft-ietf-mmusic-mdns-ice-candidates#section-3.2.2-2 - // An ICE agent SHOULD ignore candidates where the hostname resolution returns more than one IP address. - // - // We will take the first we receive which could result in a race between two suitable addresses where - // one is better than the other (e.g. localhost vs LAN). - return res.answer, res.addr, nil - case <-ctx.Done(): - return dnsmessage.ResourceHeader{}, nil, errContextElapsed - } - } -} - -type ipToBytesError struct { - ip net.IP - expectedType string -} - -func (err ipToBytesError) Error() string { - return fmt.Sprintf("ip (%s) is not %s", err.ip, err.expectedType) -} - -func ipv4ToBytes(ip net.IP) ([4]byte, error) { - rawIP := ip.To4() - if rawIP == nil { - return [4]byte{}, ipToBytesError{ip, "IPv4"} - } - - // net.IPs are stored in big endian / network byte order - var out [4]byte - copy(out[:], rawIP[:]) - return out, nil -} - -func ipv6ToBytes(ip net.IP) ([16]byte, error) { - rawIP := ip.To16() - if rawIP == nil { - return [16]byte{}, ipToBytesError{ip, "IPv6"} - } - - // net.IPs are stored in big endian / network byte order - var out [16]byte - copy(out[:], rawIP[:]) - return out, nil -} - -func interfaceForRemote(remote string) (net.IP, error) { - conn, err := net.Dial("udp", remote) - if err != nil { - return nil, err - } - - localAddr, ok := conn.LocalAddr().(*net.UDPAddr) - if !ok { - return nil, errFailedCast - } - - if err := conn.Close(); err != nil { - return nil, err - } - - return localAddr.IP, nil -} - -func (c *Conn) sendQuestion(name string) { - packedName, err := dnsmessage.NewName(name) - if err != nil { - c.log.Warnf("Failed to construct mDNS packet %v", err) - return - } - - msg := dnsmessage.Message{ - Header: dnsmessage.Header{}, - Questions: []dnsmessage.Question{ - { - Type: dnsmessage.TypeA, - Class: dnsmessage.ClassINET, - Name: packedName, - }, - }, - } - - rawQuery, err := msg.Pack() - if err != nil { - c.log.Warnf("Failed to construct mDNS packet %v", err) - return - } - - c.writeToSocket(0, rawQuery, false) -} - -func (c *Conn) writeToSocket(ifIndex int, b []byte, srcIfcIsLoopback bool) { - if ifIndex != 0 { - ifc, err := net.InterfaceByIndex(ifIndex) - if err != nil { - c.log.Warnf("Failed to get interface for %d: %v", ifIndex, err) - return - } - if srcIfcIsLoopback && ifc.Flags&net.FlagLoopback == 0 { - // avoid accidentally tricking the destination that itself is the same as us - c.log.Warnf("Interface is not loopback %d", ifIndex) - return - } - if err := c.socket.SetMulticastInterface(ifc); err != nil { - c.log.Warnf("Failed to set multicast interface for %d: %v", ifIndex, err) - } else { - if _, err := c.socket.WriteTo(b, nil, c.dstAddr); err != nil { - c.log.Warnf("Failed to send mDNS packet on interface %d: %v", ifIndex, err) - } - } - return - } - for ifcIdx := range c.ifaces { - if srcIfcIsLoopback && c.ifaces[ifcIdx].Flags&net.FlagLoopback == 0 { - // avoid accidentally tricking the destination that itself is the same as us - continue - } - if err := c.socket.SetMulticastInterface(&c.ifaces[ifcIdx]); err != nil { - c.log.Warnf("Failed to set multicast interface for %d: %v", c.ifaces[ifcIdx].Index, err) - } else { - if _, err := c.socket.WriteTo(b, nil, c.dstAddr); err != nil { - c.log.Warnf("Failed to send mDNS packet on interface %d: %v", c.ifaces[ifcIdx].Index, err) - } - } - } -} - -func createAnswer(name string, addr net.IP) (dnsmessage.Message, error) { - packedName, err := dnsmessage.NewName(name) - if err != nil { - return dnsmessage.Message{}, err - } - - msg := dnsmessage.Message{ - Header: dnsmessage.Header{ - Response: true, - Authoritative: true, - }, - Answers: []dnsmessage.Resource{ - { - Header: dnsmessage.ResourceHeader{ - Type: dnsmessage.TypeA, - Class: dnsmessage.ClassINET, - Name: packedName, - TTL: responseTTL, - }, - }, - }, - } - - if ip4 := addr.To4(); ip4 != nil { - ipBuf, err := ipv4ToBytes(addr) - if err != nil { - return dnsmessage.Message{}, err - } - msg.Answers[0].Body = &dnsmessage.AResource{ - A: ipBuf, - } - } else { - ipBuf, err := ipv6ToBytes(addr) - if err != nil { - return dnsmessage.Message{}, err - } - msg.Answers[0].Body = &dnsmessage.AAAAResource{ - AAAA: ipBuf, - } - } - - return msg, nil -} - -func (c *Conn) sendAnswer(name string, ifIndex int, addr net.IP) { - answer, err := createAnswer(name, addr) - if err != nil { - c.log.Warnf("Failed to create mDNS answer %v", err) - return - } - - rawAnswer, err := answer.Pack() - if err != nil { - c.log.Warnf("Failed to construct mDNS packet %v", err) - return - } - - c.writeToSocket(ifIndex, rawAnswer, addr.IsLoopback()) -} - -func (c *Conn) start(inboundBufferSize int, config *Config) { //nolint gocognit - defer func() { - c.mu.Lock() - defer c.mu.Unlock() - close(c.closed) - }() - - b := make([]byte, inboundBufferSize) - p := dnsmessage.Parser{} - - for { - n, cm, src, err := c.socket.ReadFrom(b) - if err != nil { - if errors.Is(err, net.ErrClosed) { - return - } - c.log.Warnf("Failed to ReadFrom %q %v", src, err) - continue - } - var ifIndex int - if cm != nil { - ifIndex = cm.IfIndex - } - var srcIP net.IP - switch addr := src.(type) { - case *net.UDPAddr: - srcIP = addr.IP - case *net.TCPAddr: - srcIP = addr.IP - default: - c.log.Warnf("Failed to determine address type %T for source address %s", src, src) - continue - } - srcIsIPv4 := srcIP.To4() != nil - - func() { - c.mu.RLock() - defer c.mu.RUnlock() - - if _, err := p.Start(b[:n]); err != nil { - c.log.Warnf("Failed to parse mDNS packet %v", err) - return - } - - for i := 0; i <= maxMessageRecords; i++ { - q, err := p.Question() - if errors.Is(err, dnsmessage.ErrSectionDone) { - break - } else if err != nil { - c.log.Warnf("Failed to parse mDNS packet %v", err) - return - } - - for _, localName := range c.localNames { - if localName == q.Name.String() { - if config.LocalAddress != nil { - c.sendAnswer(q.Name.String(), ifIndex, config.LocalAddress) - } else { - var localAddress net.IP - - // prefer the address of the interface if we know its index, but otherwise - // derive it from the address we read from. We do this because even if - // multicast loopback is in use or we send from a loopback interface, - // there are still cases where the IP packet will contain the wrong - // source IP (e.g. a LAN interface). - // For example, we can have a packet that has: - // Source: 192.168.65.3 - // Destination: 224.0.0.251 - // Interface Index: 1 - // Interface Addresses @ 1: [127.0.0.1/8 ::1/128] - if ifIndex != 0 { - ifc, netErr := net.InterfaceByIndex(ifIndex) - if netErr != nil { - c.log.Warnf("Failed to get interface for %d: %v", ifIndex, netErr) - continue - } - addrs, addrsErr := ifc.Addrs() - if addrsErr != nil { - c.log.Warnf("Failed to get addresses for interface %d: %v", ifIndex, addrsErr) - continue - } - if len(addrs) == 0 { - c.log.Warnf("Expected more than one address for interface %d", ifIndex) - continue - } - var selectedIP net.IP - for _, addr := range addrs { - var ip net.IP - switch addr := addr.(type) { - case *net.IPNet: - ip = addr.IP - case *net.IPAddr: - ip = addr.IP - default: - c.log.Warnf("Failed to determine address type %T from interface %d", addr, ifIndex) - continue - } - - // match up respective IP types - if ipv4 := ip.To4(); ipv4 == nil { - if srcIsIPv4 { - continue - } else if !isSupportedIPv6(ip) { - continue - } - } else if !srcIsIPv4 { - continue - } - selectedIP = ip - break - } - if selectedIP == nil { - c.log.Warnf("Failed to find suitable IP for interface %d; deriving address from source address instead", ifIndex) - } else { - localAddress = selectedIP - } - } else if ifIndex == 0 || localAddress == nil { - localAddress, err = interfaceForRemote(src.String()) - if err != nil { - c.log.Warnf("Failed to get local interface to communicate with %s: %v", src.String(), err) - continue - } - } - - c.sendAnswer(q.Name.String(), ifIndex, localAddress) - } - } - } - } - - for i := 0; i <= maxMessageRecords; i++ { - a, err := p.AnswerHeader() - if errors.Is(err, dnsmessage.ErrSectionDone) { - return - } - if err != nil { - c.log.Warnf("Failed to parse mDNS packet %v", err) - return - } - - if a.Type != dnsmessage.TypeA && a.Type != dnsmessage.TypeAAAA { - continue - } - - for i := len(c.queries) - 1; i >= 0; i-- { - if c.queries[i].nameWithSuffix == a.Name.String() { - ip, err := ipFromAnswerHeader(a, p) - if err != nil { - c.log.Warnf("Failed to parse mDNS answer %v", err) - return - } - - c.queries[i].queryResultChan <- queryResult{a, &net.IPAddr{ - IP: ip, - }} - c.queries = append(c.queries[:i], c.queries[i+1:]...) - } - } - } - }() - } -} - -func ipFromAnswerHeader(a dnsmessage.ResourceHeader, p dnsmessage.Parser) (ip []byte, err error) { - if a.Type == dnsmessage.TypeA { - resource, err := p.AResource() - if err != nil { - return nil, err - } - ip = resource.A[:] - } else { - resource, err := p.AAAAResource() - if err != nil { - return nil, err - } - ip = resource.AAAA[:] - } - - return -} - -// The conditions of invalidation written below are defined in -// https://tools.ietf.org/html/rfc8445#section-5.1.1.1 -func isSupportedIPv6(ip net.IP) bool { - if len(ip) != net.IPv6len || - isZeros(ip[0:12]) || // !(IPv4-compatible IPv6) - ip[0] == 0xfe && ip[1]&0xc0 == 0xc0 || // !(IPv6 site-local unicast) - ip.IsLinkLocalUnicast() || - ip.IsLinkLocalMulticast() { - return false - } - return true -} - -func isZeros(ip net.IP) bool { - for i := 0; i < len(ip); i++ { - if ip[i] != 0 { - return false - } - } - return true -} diff --git a/vendor/github.com/pion/mdns/.gitignore b/vendor/github.com/pion/mdns/v2/.gitignore similarity index 100% rename from vendor/github.com/pion/mdns/.gitignore rename to vendor/github.com/pion/mdns/v2/.gitignore diff --git a/vendor/github.com/pion/mdns/.golangci.yml b/vendor/github.com/pion/mdns/v2/.golangci.yml similarity index 100% rename from vendor/github.com/pion/mdns/.golangci.yml rename to vendor/github.com/pion/mdns/v2/.golangci.yml diff --git a/vendor/github.com/pion/mdns/.goreleaser.yml b/vendor/github.com/pion/mdns/v2/.goreleaser.yml similarity index 100% rename from vendor/github.com/pion/mdns/.goreleaser.yml rename to vendor/github.com/pion/mdns/v2/.goreleaser.yml diff --git a/vendor/github.com/pion/mdns/LICENSE b/vendor/github.com/pion/mdns/v2/LICENSE similarity index 100% rename from vendor/github.com/pion/mdns/LICENSE rename to vendor/github.com/pion/mdns/v2/LICENSE diff --git a/vendor/github.com/pion/mdns/README.md b/vendor/github.com/pion/mdns/v2/README.md similarity index 100% rename from vendor/github.com/pion/mdns/README.md rename to vendor/github.com/pion/mdns/v2/README.md diff --git a/vendor/github.com/pion/mdns/codecov.yml b/vendor/github.com/pion/mdns/v2/codecov.yml similarity index 100% rename from vendor/github.com/pion/mdns/codecov.yml rename to vendor/github.com/pion/mdns/v2/codecov.yml diff --git a/vendor/github.com/pion/mdns/config.go b/vendor/github.com/pion/mdns/v2/config.go similarity index 69% rename from vendor/github.com/pion/mdns/config.go rename to vendor/github.com/pion/mdns/v2/config.go index 34fc8fe7c5..4659e06645 100644 --- a/vendor/github.com/pion/mdns/config.go +++ b/vendor/github.com/pion/mdns/v2/config.go @@ -11,14 +11,22 @@ import ( ) const ( - // DefaultAddress is the default used by mDNS + // DefaultAddressIPv4 is the default used by mDNS // and in most cases should be the address that the - // net.Conn passed to Server is bound to - DefaultAddress = "224.0.0.0:5353" + // ipv4.PacketConn passed to Server is bound to + DefaultAddressIPv4 = "224.0.0.0:5353" + + // DefaultAddressIPv6 is the default IPv6 address used + // by mDNS and in most cases should be the address that + // the ipv6.PacketConn passed to Server is bound to + DefaultAddressIPv6 = "[FF02::]:5353" ) // Config is used to configure a mDNS client or server. type Config struct { + // Name is the name of the client/server used for logging purposes. + Name string + // QueryInterval controls how often we sends Queries until we // get a response for the requested name QueryInterval time.Duration diff --git a/vendor/github.com/pion/mdns/v2/conn.go b/vendor/github.com/pion/mdns/v2/conn.go new file mode 100644 index 0000000000..d300163ad2 --- /dev/null +++ b/vendor/github.com/pion/mdns/v2/conn.go @@ -0,0 +1,1220 @@ +// SPDX-FileCopyrightText: 2023 The Pion community +// SPDX-License-Identifier: MIT + +package mdns + +import ( + "context" + "errors" + "fmt" + "net" + "net/netip" + "sync" + "time" + + "github.com/pion/logging" + "golang.org/x/net/dns/dnsmessage" + "golang.org/x/net/ipv4" + "golang.org/x/net/ipv6" +) + +// Conn represents a mDNS Server +type Conn struct { + mu sync.RWMutex + name string + log logging.LeveledLogger + + multicastPktConnV4 ipPacketConn + multicastPktConnV6 ipPacketConn + dstAddr4 *net.UDPAddr + dstAddr6 *net.UDPAddr + + unicastPktConnV4 ipPacketConn + unicastPktConnV6 ipPacketConn + + queryInterval time.Duration + localNames []string + queries []*query + ifaces map[int]netInterface + + closed chan interface{} +} + +type query struct { + nameWithSuffix string + queryResultChan chan queryResult +} + +type queryResult struct { + answer dnsmessage.ResourceHeader + addr netip.Addr +} + +const ( + defaultQueryInterval = time.Second + destinationAddress4 = "224.0.0.251:5353" + destinationAddress6 = "[FF02::FB]:5353" + maxMessageRecords = 3 + responseTTL = 120 + // maxPacketSize is the maximum size of a mdns packet. + // From RFC 6762: + // Even when fragmentation is used, a Multicast DNS packet, including IP + // and UDP headers, MUST NOT exceed 9000 bytes. + // https://datatracker.ietf.org/doc/html/rfc6762#section-17 + maxPacketSize = 9000 +) + +var ( + errNoPositiveMTUFound = errors.New("no positive MTU found") + errNoPacketConn = errors.New("must supply at least a multicast IPv4 or IPv6 PacketConn") + errNoUsableInterfaces = errors.New("no usable interfaces found for mDNS") + errFailedToClose = errors.New("failed to close mDNS Conn") +) + +type netInterface struct { + net.Interface + ipAddrs []netip.Addr + supportsV4 bool + supportsV6 bool +} + +// Server establishes a mDNS connection over an existing conn. +// Either one or both of the multicast packet conns should be provided. +// The presence of each IP type of PacketConn will dictate what kinds +// of questions are sent for queries. That is, if an ipv6.PacketConn is +// provided, then AAAA questions will be sent. A questions will only be +// sent if an ipv4.PacketConn is also provided. In the future, we may +// add a QueryAddr method that allows specifying this more clearly. +// +//nolint:gocognit +func Server( + multicastPktConnV4 *ipv4.PacketConn, + multicastPktConnV6 *ipv6.PacketConn, + config *Config, +) (*Conn, error) { + if config == nil { + return nil, errNilConfig + } + loggerFactory := config.LoggerFactory + if loggerFactory == nil { + loggerFactory = logging.NewDefaultLoggerFactory() + } + log := loggerFactory.NewLogger("mdns") + + c := &Conn{ + queryInterval: defaultQueryInterval, + log: log, + closed: make(chan interface{}), + } + c.name = config.Name + if c.name == "" { + c.name = fmt.Sprintf("%p", &c) + } + + if multicastPktConnV4 == nil && multicastPktConnV6 == nil { + return nil, errNoPacketConn + } + + ifaces := config.Interfaces + if ifaces == nil { + var err error + ifaces, err = net.Interfaces() + if err != nil { + return nil, err + } + } + + var unicastPktConnV4 *ipv4.PacketConn + { + addr4, err := net.ResolveUDPAddr("udp4", "0.0.0.0:0") + if err != nil { + return nil, err + } + + unicastConnV4, err := net.ListenUDP("udp4", addr4) + if err != nil { + log.Warnf("[%s] failed to listen on unicast IPv4 %s: %s; will not be able to receive unicast responses on IPv4", c.name, addr4, err) + } else { + unicastPktConnV4 = ipv4.NewPacketConn(unicastConnV4) + } + } + + var unicastPktConnV6 *ipv6.PacketConn + { + addr6, err := net.ResolveUDPAddr("udp6", "[::]:") + if err != nil { + return nil, err + } + + unicastConnV6, err := net.ListenUDP("udp6", addr6) + if err != nil { + log.Warnf("[%s] failed to listen on unicast IPv6 %s: %s; will not be able to receive unicast responses on IPv6", c.name, addr6, err) + } else { + unicastPktConnV6 = ipv6.NewPacketConn(unicastConnV6) + } + } + + mutlicastGroup4 := net.IPv4(224, 0, 0, 251) + multicastGroupAddr4 := &net.UDPAddr{IP: mutlicastGroup4} + + // FF02::FB + mutlicastGroup6 := net.IP{0xff, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfb} + multicastGroupAddr6 := &net.UDPAddr{IP: mutlicastGroup6} + + inboundBufferSize := 0 + joinErrCount := 0 + ifacesToUse := make(map[int]netInterface, len(ifaces)) + for i := range ifaces { + ifc := ifaces[i] + if !config.IncludeLoopback && ifc.Flags&net.FlagLoopback == net.FlagLoopback { + continue + } + if ifc.Flags&net.FlagUp == 0 { + continue + } + + addrs, err := ifc.Addrs() + if err != nil { + continue + } + var supportsV4, supportsV6 bool + ifcIPAddrs := make([]netip.Addr, 0, len(addrs)) + for _, addr := range addrs { + var ipToConv net.IP + switch addr := addr.(type) { + case *net.IPNet: + ipToConv = addr.IP + case *net.IPAddr: + ipToConv = addr.IP + default: + continue + } + + ipAddr, ok := netip.AddrFromSlice(ipToConv) + if !ok { + continue + } + if multicastPktConnV4 != nil { + // don't want mapping since we also support IPv4/A + ipAddr = ipAddr.Unmap() + } + ipAddr = addrWithOptionalZone(ipAddr, ifc.Name) + + if ipAddr.Is6() && !ipAddr.Is4In6() { + supportsV6 = true + } else { + // we'll claim we support v4 but defer if we send it or not + // based on IPv4-to-IPv6 mapping rules later (search for Is4In6 below) + supportsV4 = true + } + ifcIPAddrs = append(ifcIPAddrs, ipAddr) + } + if !(supportsV4 || supportsV6) { + continue + } + + var atLeastOneJoin bool + if supportsV4 && multicastPktConnV4 != nil { + if err := multicastPktConnV4.JoinGroup(&ifc, multicastGroupAddr4); err == nil { + atLeastOneJoin = true + } + } + if supportsV6 && multicastPktConnV6 != nil { + if err := multicastPktConnV6.JoinGroup(&ifc, multicastGroupAddr6); err == nil { + atLeastOneJoin = true + } + } + if !atLeastOneJoin { + joinErrCount++ + continue + } + + ifacesToUse[ifc.Index] = netInterface{ + Interface: ifc, + ipAddrs: ifcIPAddrs, + supportsV4: supportsV4, + supportsV6: supportsV6, + } + if ifc.MTU > inboundBufferSize { + inboundBufferSize = ifc.MTU + } + } + + if len(ifacesToUse) == 0 { + return nil, errNoUsableInterfaces + } + if inboundBufferSize == 0 { + return nil, errNoPositiveMTUFound + } + if inboundBufferSize > maxPacketSize { + inboundBufferSize = maxPacketSize + } + if joinErrCount >= len(ifaces) { + return nil, errJoiningMulticastGroup + } + + dstAddr4, err := net.ResolveUDPAddr("udp4", destinationAddress4) + if err != nil { + return nil, err + } + + dstAddr6, err := net.ResolveUDPAddr("udp6", destinationAddress6) + if err != nil { + return nil, err + } + + var localNames []string + for _, l := range config.LocalNames { + localNames = append(localNames, l+".") + } + + c.dstAddr4 = dstAddr4 + c.dstAddr6 = dstAddr6 + c.localNames = localNames + c.ifaces = ifacesToUse + + if config.QueryInterval != 0 { + c.queryInterval = config.QueryInterval + } + + if multicastPktConnV4 != nil { + if err := multicastPktConnV4.SetControlMessage(ipv4.FlagInterface, true); err != nil { + c.log.Warnf("[%s] failed to SetControlMessage(ipv4.FlagInterface) on multicast IPv4 PacketConn %v", c.name, err) + } + if err := multicastPktConnV4.SetControlMessage(ipv4.FlagDst, true); err != nil { + c.log.Warnf("[%s] failed to SetControlMessage(ipv4.FlagDst) on multicast IPv4 PacketConn %v", c.name, err) + } + c.multicastPktConnV4 = ipPacketConn4{c.name, multicastPktConnV4, log} + } + if multicastPktConnV6 != nil { + if err := multicastPktConnV6.SetControlMessage(ipv6.FlagInterface, true); err != nil { + c.log.Warnf("[%s] failed to SetControlMessage(ipv6.FlagInterface) on multicast IPv6 PacketConn %v", c.name, err) + } + if err := multicastPktConnV6.SetControlMessage(ipv6.FlagDst, true); err != nil { + c.log.Warnf("[%s] failed to SetControlMessage(ipv6.FlagInterface) on multicast IPv6 PacketConn %v", c.name, err) + } + c.multicastPktConnV6 = ipPacketConn6{c.name, multicastPktConnV6, log} + } + if unicastPktConnV4 != nil { + if err := unicastPktConnV4.SetControlMessage(ipv4.FlagInterface, true); err != nil { + c.log.Warnf("[%s] failed to SetControlMessage(ipv4.FlagInterface) on unicast IPv4 PacketConn %v", c.name, err) + } + if err := unicastPktConnV4.SetControlMessage(ipv4.FlagDst, true); err != nil { + c.log.Warnf("[%s] failed to SetControlMessage(ipv4.FlagInterface) on unicast IPv4 PacketConn %v", c.name, err) + } + c.unicastPktConnV4 = ipPacketConn4{c.name, unicastPktConnV4, log} + } + if unicastPktConnV6 != nil { + if err := unicastPktConnV6.SetControlMessage(ipv6.FlagInterface, true); err != nil { + c.log.Warnf("[%s] failed to SetControlMessage(ipv6.FlagInterface) on unicast IPv6 PacketConn %v", c.name, err) + } + if err := unicastPktConnV6.SetControlMessage(ipv6.FlagDst, true); err != nil { + c.log.Warnf("[%s] failed to SetControlMessage(ipv6.FlagInterface) on unicast IPv6 PacketConn %v", c.name, err) + } + c.unicastPktConnV6 = ipPacketConn6{c.name, unicastPktConnV6, log} + } + + if config.IncludeLoopback { + // this is an efficient way for us to send ourselves a message faster instead of it going + // further out into the network stack. + if multicastPktConnV4 != nil { + if err := multicastPktConnV4.SetMulticastLoopback(true); err != nil { + c.log.Warnf("[%s] failed to SetMulticastLoopback(true) on multicast IPv4 PacketConn %v; this may cause inefficient network path c.name,communications", c.name, err) + } + } + if multicastPktConnV6 != nil { + if err := multicastPktConnV6.SetMulticastLoopback(true); err != nil { + c.log.Warnf("[%s] failed to SetMulticastLoopback(true) on multicast IPv6 PacketConn %v; this may cause inefficient network path c.name,communications", c.name, err) + } + } + if unicastPktConnV4 != nil { + if err := unicastPktConnV4.SetMulticastLoopback(true); err != nil { + c.log.Warnf("[%s] failed to SetMulticastLoopback(true) on unicast IPv4 PacketConn %v; this may cause inefficient network path c.name,communications", c.name, err) + } + } + if unicastPktConnV6 != nil { + if err := unicastPktConnV6.SetMulticastLoopback(true); err != nil { + c.log.Warnf("[%s] failed to SetMulticastLoopback(true) on unicast IPv6 PacketConn %v; this may cause inefficient network path c.name,communications", c.name, err) + } + } + } + + // https://www.rfc-editor.org/rfc/rfc6762.html#section-17 + // Multicast DNS messages carried by UDP may be up to the IP MTU of the + // physical interface, less the space required for the IP header (20 + // bytes for IPv4; 40 bytes for IPv6) and the UDP header (8 bytes). + started := make(chan struct{}) + go c.start(started, inboundBufferSize-20-8, config) + <-started + return c, nil +} + +// Close closes the mDNS Conn +func (c *Conn) Close() error { + select { + case <-c.closed: + return nil + default: + } + + // Once on go1.20, can use errors.Join + var errs []error + if c.multicastPktConnV4 != nil { + if err := c.multicastPktConnV4.Close(); err != nil { + errs = append(errs, err) + } + } + + if c.multicastPktConnV6 != nil { + if err := c.multicastPktConnV6.Close(); err != nil { + errs = append(errs, err) + } + } + + if c.unicastPktConnV4 != nil { + if err := c.unicastPktConnV4.Close(); err != nil { + errs = append(errs, err) + } + } + + if c.unicastPktConnV6 != nil { + if err := c.unicastPktConnV6.Close(); err != nil { + errs = append(errs, err) + } + } + + if len(errs) == 0 { + <-c.closed + return nil + } + + rtrn := errFailedToClose + for _, err := range errs { + rtrn = fmt.Errorf("%w\n%w", err, rtrn) + } + return rtrn +} + +// Query sends mDNS Queries for the following name until +// either the Context is canceled/expires or we get a result +// +// Deprecated: Use QueryAddr instead as it supports the easier to use netip.Addr. +func (c *Conn) Query(ctx context.Context, name string) (dnsmessage.ResourceHeader, net.Addr, error) { + header, addr, err := c.QueryAddr(ctx, name) + if err != nil { + return header, nil, err + } + return header, &net.IPAddr{ + IP: addr.AsSlice(), + Zone: addr.Zone(), + }, nil +} + +// QueryAddr sends mDNS Queries for the following name until +// either the Context is canceled/expires or we get a result +func (c *Conn) QueryAddr(ctx context.Context, name string) (dnsmessage.ResourceHeader, netip.Addr, error) { + select { + case <-c.closed: + return dnsmessage.ResourceHeader{}, netip.Addr{}, errConnectionClosed + default: + } + + nameWithSuffix := name + "." + + queryChan := make(chan queryResult, 1) + query := &query{nameWithSuffix, queryChan} + c.mu.Lock() + c.queries = append(c.queries, query) + c.mu.Unlock() + + defer func() { + c.mu.Lock() + defer c.mu.Unlock() + for i := len(c.queries) - 1; i >= 0; i-- { + if c.queries[i] == query { + c.queries = append(c.queries[:i], c.queries[i+1:]...) + } + } + }() + + ticker := time.NewTicker(c.queryInterval) + defer ticker.Stop() + + c.sendQuestion(nameWithSuffix) + for { + select { + case <-ticker.C: + c.sendQuestion(nameWithSuffix) + case <-c.closed: + return dnsmessage.ResourceHeader{}, netip.Addr{}, errConnectionClosed + case res := <-queryChan: + // Given https://datatracker.ietf.org/doc/html/draft-ietf-mmusic-mdns-ice-candidates#section-3.2.2-2 + // An ICE agent SHOULD ignore candidates where the hostname resolution returns more than one IP address. + // + // We will take the first we receive which could result in a race between two suitable addresses where + // one is better than the other (e.g. localhost vs LAN). + return res.answer, res.addr, nil + case <-ctx.Done(): + return dnsmessage.ResourceHeader{}, netip.Addr{}, errContextElapsed + } + } +} + +type ipToBytesError struct { + addr netip.Addr + expectedType string +} + +func (err ipToBytesError) Error() string { + return fmt.Sprintf("ip (%s) is not %s", err.addr, err.expectedType) +} + +// assumes ipv4-to-ipv6 mapping has been checked +func ipv4ToBytes(ipAddr netip.Addr) ([4]byte, error) { + if !ipAddr.Is4() { + return [4]byte{}, ipToBytesError{ipAddr, "IPv4"} + } + + md, err := ipAddr.MarshalBinary() + if err != nil { + return [4]byte{}, err + } + + // net.IPs are stored in big endian / network byte order + var out [4]byte + copy(out[:], md) + return out, nil +} + +// assumes ipv4-to-ipv6 mapping has been checked +func ipv6ToBytes(ipAddr netip.Addr) ([16]byte, error) { + if !ipAddr.Is6() { + return [16]byte{}, ipToBytesError{ipAddr, "IPv6"} + } + md, err := ipAddr.MarshalBinary() + if err != nil { + return [16]byte{}, err + } + + // net.IPs are stored in big endian / network byte order + var out [16]byte + copy(out[:], md) + return out, nil +} + +type ipToAddrError struct { + ip []byte +} + +func (err ipToAddrError) Error() string { + return fmt.Sprintf("failed to convert ip address '%s' to netip.Addr", err.ip) +} + +func interfaceForRemote(remote string) (*netip.Addr, error) { + conn, err := net.Dial("udp", remote) + if err != nil { + return nil, err + } + + localAddr, ok := conn.LocalAddr().(*net.UDPAddr) + if !ok { + return nil, errFailedCast + } + + if err := conn.Close(); err != nil { + return nil, err + } + + ipAddr, ok := netip.AddrFromSlice(localAddr.IP) + if !ok { + return nil, ipToAddrError{localAddr.IP} + } + ipAddr = addrWithOptionalZone(ipAddr, localAddr.Zone) + return &ipAddr, nil +} + +type writeType byte + +const ( + writeTypeQuestion writeType = iota + writeTypeAnswer +) + +func (c *Conn) sendQuestion(name string) { + packedName, err := dnsmessage.NewName(name) + if err != nil { + c.log.Warnf("[%s] failed to construct mDNS packet %v", c.name, err) + return + } + + // https://datatracker.ietf.org/doc/html/draft-ietf-rtcweb-mdns-ice-candidates-04#section-3.2.1 + // + // 2. Otherwise, resolve the candidate using mDNS. The ICE agent + // SHOULD set the unicast-response bit of the corresponding mDNS + // query message; this minimizes multicast traffic, as the response + // is probably only useful to the querying node. + // + // 18.12. Repurposing of Top Bit of qclass in Question Section + // + // In the Question Section of a Multicast DNS query, the top bit of the + // qclass field is used to indicate that unicast responses are preferred + // for this particular question. (See Section 5.4.) + // + // We'll follow this up sending on our unicast based packet connections so that we can + // get a unicast response back. + msg := dnsmessage.Message{ + Header: dnsmessage.Header{}, + } + + // limit what we ask for based on what IPv is available. In the future, + // this could be an option since there's no reason you cannot get an + // A record on an IPv6 sourced question and vice versa. + if c.multicastPktConnV4 != nil { + msg.Questions = append(msg.Questions, dnsmessage.Question{ + Type: dnsmessage.TypeA, + Class: dnsmessage.ClassINET | (1 << 15), + Name: packedName, + }) + } + if c.multicastPktConnV6 != nil { + msg.Questions = append(msg.Questions, dnsmessage.Question{ + Type: dnsmessage.TypeAAAA, + Class: dnsmessage.ClassINET | (1 << 15), + Name: packedName, + }) + } + + rawQuery, err := msg.Pack() + if err != nil { + c.log.Warnf("[%s] failed to construct mDNS packet %v", c.name, err) + return + } + + c.writeToSocket(-1, rawQuery, false, false, writeTypeQuestion, nil) +} + +//nolint:gocognit +func (c *Conn) writeToSocket( + ifIndex int, + b []byte, + hasLoopbackData bool, + hasIPv6Zone bool, + wType writeType, + unicastDst *net.UDPAddr, +) { + var dst4, dst6 net.Addr + if wType == writeTypeAnswer { + if unicastDst == nil { + dst4 = c.dstAddr4 + dst6 = c.dstAddr6 + } else { + if unicastDst.IP.To4() == nil { + dst6 = unicastDst + } else { + dst4 = unicastDst + } + } + } + + if ifIndex != -1 { + if wType == writeTypeQuestion { + c.log.Errorf("[%s] Unexpected question using specific interface index %d; dropping question", c.name, ifIndex) + return + } + + ifc, ok := c.ifaces[ifIndex] + if !ok { + c.log.Warnf("[%s] no interface for %d", c.name, ifIndex) + return + } + if hasLoopbackData && ifc.Flags&net.FlagLoopback == 0 { + // avoid accidentally tricking the destination that itself is the same as us + c.log.Debugf("[%s] interface is not loopback %d", c.name, ifIndex) + return + } + + c.log.Debugf("[%s] writing answer to IPv4: %v, IPv6: %v", c.name, dst4, dst6) + + if ifc.supportsV4 && c.multicastPktConnV4 != nil && dst4 != nil { + if !hasIPv6Zone { + if _, err := c.multicastPktConnV4.WriteTo(b, &ifc.Interface, nil, dst4); err != nil { + c.log.Warnf("[%s] failed to send mDNS packet on IPv4 interface %d: %v", c.name, ifIndex, err) + } + } else { + c.log.Debugf("[%s] refusing to send mDNS packet with IPv6 zone over IPv4", c.name) + } + } + if ifc.supportsV6 && c.multicastPktConnV6 != nil && dst6 != nil { + if _, err := c.multicastPktConnV6.WriteTo(b, &ifc.Interface, nil, dst6); err != nil { + c.log.Warnf("[%s] failed to send mDNS packet on IPv6 interface %d: %v", c.name, ifIndex, err) + } + } + + return + } + for ifcIdx := range c.ifaces { + ifc := c.ifaces[ifcIdx] + if hasLoopbackData { + c.log.Debugf("[%s] Refusing to send loopback data with non-specific interface", c.name) + continue + } + + if wType == writeTypeQuestion { + // we'll write via unicast if we can in case the responder chooses to respond to the address the request + // came from (i.e. not respecting unicast-response bit). If we were to use the multicast packet + // conn here, we'd be writing from a specific multicast address which won't be able to receive unicast + // traffic (it only works when listening on 0.0.0.0/[::]). + if c.unicastPktConnV4 == nil && c.unicastPktConnV6 == nil { + c.log.Debugf("[%s] writing question to multicast IPv4/6 %s", c.name, c.dstAddr4) + if ifc.supportsV4 && c.multicastPktConnV4 != nil { + if _, err := c.multicastPktConnV4.WriteTo(b, &ifc.Interface, nil, c.dstAddr4); err != nil { + c.log.Warnf("[%s] failed to send mDNS packet (multicast) on IPv4 interface %d: %v", c.name, ifc.Index, err) + } + } + if ifc.supportsV6 && c.multicastPktConnV6 != nil { + if _, err := c.multicastPktConnV6.WriteTo(b, &ifc.Interface, nil, c.dstAddr6); err != nil { + c.log.Warnf("[%s] failed to send mDNS packet (multicast) on IPv6 interface %d: %v", c.name, ifc.Index, err) + } + } + } + if ifc.supportsV4 && c.unicastPktConnV4 != nil { + c.log.Debugf("[%s] writing question to unicast IPv4 %s", c.name, c.dstAddr4) + if _, err := c.unicastPktConnV4.WriteTo(b, &ifc.Interface, nil, c.dstAddr4); err != nil { + c.log.Warnf("[%s] failed to send mDNS packet (unicast) on interface %d: %v", c.name, ifc.Index, err) + } + } + if ifc.supportsV6 && c.unicastPktConnV6 != nil { + c.log.Debugf("[%s] writing question to unicast IPv6 %s", c.name, c.dstAddr6) + if _, err := c.unicastPktConnV6.WriteTo(b, &ifc.Interface, nil, c.dstAddr6); err != nil { + c.log.Warnf("[%s] failed to send mDNS packet (unicast) on interface %d: %v", c.name, ifc.Index, err) + } + } + } else { + c.log.Debugf("[%s] writing answer to IPv4: %v, IPv6: %v", c.name, dst4, dst6) + + if ifc.supportsV4 && c.multicastPktConnV4 != nil && dst4 != nil { + if !hasIPv6Zone { + if _, err := c.multicastPktConnV4.WriteTo(b, &ifc.Interface, nil, dst4); err != nil { + c.log.Warnf("[%s] failed to send mDNS packet (multicast) on IPv4 interface %d: %v", c.name, ifIndex, err) + } + } else { + c.log.Debugf("[%s] refusing to send mDNS packet with IPv6 zone over IPv4", c.name) + } + } + if ifc.supportsV6 && c.multicastPktConnV6 != nil && dst6 != nil { + if _, err := c.multicastPktConnV6.WriteTo(b, &ifc.Interface, nil, dst6); err != nil { + c.log.Warnf("[%s] failed to send mDNS packet (multicast) on IPv6 interface %d: %v", c.name, ifIndex, err) + } + } + } + } +} + +func createAnswer(id uint16, name string, addr netip.Addr) (dnsmessage.Message, error) { + packedName, err := dnsmessage.NewName(name) + if err != nil { + return dnsmessage.Message{}, err + } + + msg := dnsmessage.Message{ + Header: dnsmessage.Header{ + ID: id, + Response: true, + Authoritative: true, + }, + Answers: []dnsmessage.Resource{ + { + Header: dnsmessage.ResourceHeader{ + Class: dnsmessage.ClassINET, + Name: packedName, + TTL: responseTTL, + }, + }, + }, + } + + if addr.Is4() { + ipBuf, err := ipv4ToBytes(addr) + if err != nil { + return dnsmessage.Message{}, err + } + msg.Answers[0].Header.Type = dnsmessage.TypeA + msg.Answers[0].Body = &dnsmessage.AResource{ + A: ipBuf, + } + } else if addr.Is6() { + // we will lose the zone here, but the receiver can reconstruct it + ipBuf, err := ipv6ToBytes(addr) + if err != nil { + return dnsmessage.Message{}, err + } + msg.Answers[0].Header.Type = dnsmessage.TypeAAAA + msg.Answers[0].Body = &dnsmessage.AAAAResource{ + AAAA: ipBuf, + } + } + + return msg, nil +} + +func (c *Conn) sendAnswer(queryID uint16, name string, ifIndex int, result netip.Addr, dst *net.UDPAddr) { + answer, err := createAnswer(queryID, name, result) + if err != nil { + c.log.Warnf("[%s] failed to create mDNS answer %v", c.name, err) + return + } + + rawAnswer, err := answer.Pack() + if err != nil { + c.log.Warnf("[%s] failed to construct mDNS packet %v", c.name, err) + return + } + + c.writeToSocket( + ifIndex, + rawAnswer, + result.IsLoopback(), + result.Is6() && result.Zone() != "", + writeTypeAnswer, + dst, + ) +} + +type ipControlMessage struct { + IfIndex int + Dst net.IP +} + +type ipPacketConn interface { + ReadFrom(b []byte) (n int, cm *ipControlMessage, src net.Addr, err error) + WriteTo(b []byte, via *net.Interface, cm *ipControlMessage, dst net.Addr) (n int, err error) + Close() error +} + +type ipPacketConn4 struct { + name string + conn *ipv4.PacketConn + log logging.LeveledLogger +} + +func (c ipPacketConn4) ReadFrom(b []byte) (n int, cm *ipControlMessage, src net.Addr, err error) { + n, cm4, src, err := c.conn.ReadFrom(b) + if err != nil || cm4 == nil { + return n, nil, src, err + } + return n, &ipControlMessage{IfIndex: cm4.IfIndex, Dst: cm4.Dst}, src, err +} + +func (c ipPacketConn4) WriteTo(b []byte, via *net.Interface, cm *ipControlMessage, dst net.Addr) (n int, err error) { + var cm4 *ipv4.ControlMessage + if cm != nil { + cm4 = &ipv4.ControlMessage{ + IfIndex: cm.IfIndex, + } + } + if err := c.conn.SetMulticastInterface(via); err != nil { + c.log.Warnf("[%s] failed to set multicast interface for %d: %v", c.name, via.Index, err) + return 0, err + } + return c.conn.WriteTo(b, cm4, dst) +} + +func (c ipPacketConn4) Close() error { + return c.conn.Close() +} + +type ipPacketConn6 struct { + name string + conn *ipv6.PacketConn + log logging.LeveledLogger +} + +func (c ipPacketConn6) ReadFrom(b []byte) (n int, cm *ipControlMessage, src net.Addr, err error) { + n, cm6, src, err := c.conn.ReadFrom(b) + if err != nil || cm6 == nil { + return n, nil, src, err + } + return n, &ipControlMessage{IfIndex: cm6.IfIndex, Dst: cm6.Dst}, src, err +} + +func (c ipPacketConn6) WriteTo(b []byte, via *net.Interface, cm *ipControlMessage, dst net.Addr) (n int, err error) { + var cm6 *ipv6.ControlMessage + if cm != nil { + cm6 = &ipv6.ControlMessage{ + IfIndex: cm.IfIndex, + } + } + if err := c.conn.SetMulticastInterface(via); err != nil { + c.log.Warnf("[%s] failed to set multicast interface for %d: %v", c.name, via.Index, err) + return 0, err + } + return c.conn.WriteTo(b, cm6, dst) +} + +func (c ipPacketConn6) Close() error { + return c.conn.Close() +} + +func (c *Conn) readLoop(name string, pktConn ipPacketConn, inboundBufferSize int, config *Config) { //nolint:gocognit + b := make([]byte, inboundBufferSize) + p := dnsmessage.Parser{} + + for { + n, cm, src, err := pktConn.ReadFrom(b) + if err != nil { + if errors.Is(err, net.ErrClosed) { + return + } + c.log.Warnf("[%s] failed to ReadFrom %q %v", c.name, src, err) + continue + } + c.log.Debugf("[%s] got read on %s from %s", c.name, name, src) + + var ifIndex int + var pktDst net.IP + if cm != nil { + ifIndex = cm.IfIndex + pktDst = cm.Dst + } else { + ifIndex = -1 + } + srcAddr, ok := src.(*net.UDPAddr) + if !ok { + c.log.Warnf("[%s] expected source address %s to be UDP but got %", c.name, src, src) + continue + } + + func() { + header, err := p.Start(b[:n]) + if err != nil { + c.log.Warnf("[%s] failed to parse mDNS packet %v", c.name, err) + return + } + + for i := 0; i <= maxMessageRecords; i++ { + q, err := p.Question() + if errors.Is(err, dnsmessage.ErrSectionDone) { + break + } else if err != nil { + c.log.Warnf("[%s] failed to parse mDNS packet %v", c.name, err) + return + } + + if q.Type != dnsmessage.TypeA && q.Type != dnsmessage.TypeAAAA { + continue + } + + // https://datatracker.ietf.org/doc/html/rfc6762#section-6 + // The destination UDP port in all Multicast DNS responses MUST be 5353, + // and the destination address MUST be the mDNS IPv4 link-local + // multicast address 224.0.0.251 or its IPv6 equivalent FF02::FB, except + // when generating a reply to a query that explicitly requested a + // unicast response + shouldUnicastResponse := (q.Class&(1<<15)) != 0 || // via the unicast-response bit + srcAddr.Port != 5353 || // by virtue of being a legacy query (Section 6.7), or + (len(pktDst) != 0 && !(pktDst.Equal(c.dstAddr4.IP) || // by virtue of being a direct unicast query + pktDst.Equal(c.dstAddr6.IP))) + var dst *net.UDPAddr + if shouldUnicastResponse { + dst = srcAddr + } + + queryWantsV4 := q.Type == dnsmessage.TypeA + + for _, localName := range c.localNames { + if localName == q.Name.String() { + var localAddress *netip.Addr + if config.LocalAddress != nil { + // this means the LocalAddress does not support link-local since + // we have no zone to set here. + ipAddr, ok := netip.AddrFromSlice(config.LocalAddress) + if !ok { + c.log.Warnf("[%s] failed to convert config.LocalAddress '%s' to netip.Addr", c.name, config.LocalAddress) + continue + } + if c.multicastPktConnV4 != nil { + // don't want mapping since we also support IPv4/A + ipAddr = ipAddr.Unmap() + } + localAddress = &ipAddr + } else { + // prefer the address of the interface if we know its index, but otherwise + // derive it from the address we read from. We do this because even if + // multicast loopback is in use or we send from a loopback interface, + // there are still cases where the IP packet will contain the wrong + // source IP (e.g. a LAN interface). + // For example, we can have a packet that has: + // Source: 192.168.65.3 + // Destination: 224.0.0.251 + // Interface Index: 1 + // Interface Addresses @ 1: [127.0.0.1/8 ::1/128] + if ifIndex != -1 { + ifc, ok := c.ifaces[ifIndex] + if !ok { + c.log.Warnf("[%s] no interface for %d", c.name, ifIndex) + return + } + var selectedAddrs []netip.Addr + for _, addr := range ifc.ipAddrs { + addrCopy := addr + + // match up respective IP types based on question + if queryWantsV4 { + if addrCopy.Is4In6() { + // we may allow 4-in-6, but the question wants an A record + addrCopy = addrCopy.Unmap() + } + if !addrCopy.Is4() { + continue + } + } else { // queryWantsV6 + if !addrCopy.Is6() { + continue + } + if !isSupportedIPv6(addrCopy, c.multicastPktConnV4 == nil) { + c.log.Debugf("[%s] interface %d address not a supported IPv6 address %s", c.name, ifIndex, &addrCopy) + continue + } + } + + selectedAddrs = append(selectedAddrs, addrCopy) + } + if len(selectedAddrs) == 0 { + c.log.Debugf("[%s] failed to find suitable IP for interface %d; deriving address from source address c.name,instead", c.name, ifIndex) + } else { + // choose the best match + var choice *netip.Addr + for _, option := range selectedAddrs { + optCopy := option + if option.Is4() { + // select first + choice = &optCopy + break + } + // we're okay with 4In6 for now but ideally we get a an actual IPv6. + // Maybe in the future we never want this but it does look like Docker + // can route IPv4 over IPv6. + if choice == nil { + choice = &optCopy + } else if !optCopy.Is4In6() { + choice = &optCopy + } + if !optCopy.Is4In6() { + break + } + // otherwise keep searching for an actual IPv6 + } + localAddress = choice + } + } + if ifIndex == -1 || localAddress == nil { + localAddress, err = interfaceForRemote(src.String()) + if err != nil { + c.log.Warnf("[%s] failed to get local interface to communicate with %s: %v", c.name, src.String(), err) + continue + } + } + } + if queryWantsV4 { + if !localAddress.Is4() { + c.log.Debugf("[%s] have IPv6 address %s to respond with but question is for A not c.name,AAAA", c.name, localAddress) + continue + } + } else { + if !localAddress.Is6() { + c.log.Debugf("[%s] have IPv4 address %s to respond with but question is for AAAA not c.name,A", c.name, localAddress) + continue + } + if !isSupportedIPv6(*localAddress, c.multicastPktConnV4 == nil) { + c.log.Debugf("[%s] got local interface address but not a supported IPv6 address %v", c.name, localAddress) + continue + } + } + + if dst != nil && len(dst.IP) == net.IPv4len && + localAddress.Is6() && + localAddress.Zone() != "" && + (localAddress.IsLinkLocalUnicast() || localAddress.IsLinkLocalMulticast()) { + // This case happens when multicast v4 picks up an AAAA question that has a zone + // in the address. Since we cannot send this zone over DNS (it's meaningless), + // the other side can only infer this via the response interface on the other + // side (some IPv6 interface). + c.log.Debugf("[%s] refusing to send link-local address %s to an IPv4 destination %s", c.name, localAddress, dst) + continue + } + c.log.Debugf("[%s] sending response for %s on ifc %d of %s to %s", c.name, q.Name, ifIndex, *localAddress, dst) + c.sendAnswer(header.ID, q.Name.String(), ifIndex, *localAddress, dst) + } + } + } + + for i := 0; i <= maxMessageRecords; i++ { + a, err := p.AnswerHeader() + if errors.Is(err, dnsmessage.ErrSectionDone) { + return + } + if err != nil { + c.log.Warnf("[%s] failed to parse mDNS packet %v", c.name, err) + return + } + + if a.Type != dnsmessage.TypeA && a.Type != dnsmessage.TypeAAAA { + continue + } + + c.mu.Lock() + queries := make([]*query, len(c.queries)) + copy(queries, c.queries) + c.mu.Unlock() + + var answered []*query + for _, query := range queries { + queryCopy := query + if queryCopy.nameWithSuffix == a.Name.String() { + addr, err := addrFromAnswerHeader(a, p) + if err != nil { + c.log.Warnf("[%s] failed to parse mDNS answer %v", c.name, err) + return + } + + resultAddr := *addr + // DNS records don't contain IPv6 zones. + // We're trusting that since we're on the same link, that we will only + // be sent link-local addresses from that source's interface's address. + // If it's not present, we're out of luck since we cannot rely on the + // interface zone to be the same as the source's. + resultAddr = addrWithOptionalZone(resultAddr, srcAddr.Zone) + + select { + case queryCopy.queryResultChan <- queryResult{a, resultAddr}: + answered = append(answered, queryCopy) + default: + } + } + } + + c.mu.Lock() + for queryIdx := len(c.queries) - 1; queryIdx >= 0; queryIdx-- { + for answerIdx := len(answered) - 1; answerIdx >= 0; answerIdx-- { + if c.queries[queryIdx] == answered[answerIdx] { + c.queries = append(c.queries[:queryIdx], c.queries[queryIdx+1:]...) + answered = append(answered[:answerIdx], answered[answerIdx+1:]...) + queryIdx-- + break + } + } + } + c.mu.Unlock() + } + }() + } +} + +func (c *Conn) start(started chan<- struct{}, inboundBufferSize int, config *Config) { + defer func() { + c.mu.Lock() + defer c.mu.Unlock() + close(c.closed) + }() + + var numReaders int + readerStarted := make(chan struct{}) + readerEnded := make(chan struct{}) + + if c.multicastPktConnV4 != nil { + numReaders++ + go func() { + defer func() { + readerEnded <- struct{}{} + }() + readerStarted <- struct{}{} + c.readLoop("multi4", c.multicastPktConnV4, inboundBufferSize, config) + }() + } + if c.multicastPktConnV6 != nil { + numReaders++ + go func() { + defer func() { + readerEnded <- struct{}{} + }() + readerStarted <- struct{}{} + c.readLoop("multi6", c.multicastPktConnV6, inboundBufferSize, config) + }() + } + if c.unicastPktConnV4 != nil { + numReaders++ + go func() { + defer func() { + readerEnded <- struct{}{} + }() + readerStarted <- struct{}{} + c.readLoop("uni4", c.unicastPktConnV4, inboundBufferSize, config) + }() + } + if c.unicastPktConnV6 != nil { + numReaders++ + go func() { + defer func() { + readerEnded <- struct{}{} + }() + readerStarted <- struct{}{} + c.readLoop("uni6", c.unicastPktConnV6, inboundBufferSize, config) + }() + } + for i := 0; i < numReaders; i++ { + <-readerStarted + } + close(started) + for i := 0; i < numReaders; i++ { + <-readerEnded + } +} + +func addrFromAnswerHeader(a dnsmessage.ResourceHeader, p dnsmessage.Parser) (addr *netip.Addr, err error) { + if a.Type == dnsmessage.TypeA { + resource, err := p.AResource() + if err != nil { + return nil, err + } + ipAddr, ok := netip.AddrFromSlice(resource.A[:]) + if !ok { + return nil, fmt.Errorf("failed to convert A record: %w", ipToAddrError{resource.A[:]}) + } + ipAddr = ipAddr.Unmap() // do not want 4-in-6 + addr = &ipAddr + } else { + resource, err := p.AAAAResource() + if err != nil { + return nil, err + } + ipAddr, ok := netip.AddrFromSlice(resource.AAAA[:]) + if !ok { + return nil, fmt.Errorf("failed to convert AAAA record: %w", ipToAddrError{resource.AAAA[:]}) + } + addr = &ipAddr + } + + return +} + +func isSupportedIPv6(addr netip.Addr, ipv6Only bool) bool { + if !addr.Is6() { + return false + } + // IPv4-mapped-IPv6 addresses cannot be connected to unless + // unmapped. + if !ipv6Only && addr.Is4In6() { + return false + } + return true +} + +func addrWithOptionalZone(addr netip.Addr, zone string) netip.Addr { + if zone == "" { + return addr + } + if addr.Is6() && (addr.IsLinkLocalUnicast() || addr.IsLinkLocalMulticast()) { + return addr.WithZone(zone) + } + return addr +} diff --git a/vendor/github.com/pion/mdns/errors.go b/vendor/github.com/pion/mdns/v2/errors.go similarity index 100% rename from vendor/github.com/pion/mdns/errors.go rename to vendor/github.com/pion/mdns/v2/errors.go diff --git a/vendor/github.com/pion/mdns/mdns.go b/vendor/github.com/pion/mdns/v2/mdns.go similarity index 100% rename from vendor/github.com/pion/mdns/mdns.go rename to vendor/github.com/pion/mdns/v2/mdns.go diff --git a/vendor/github.com/pion/mdns/renovate.json b/vendor/github.com/pion/mdns/v2/renovate.json similarity index 100% rename from vendor/github.com/pion/mdns/renovate.json rename to vendor/github.com/pion/mdns/v2/renovate.json diff --git a/vendor/github.com/pion/srtp/v2/AUTHORS.txt b/vendor/github.com/pion/srtp/v2/AUTHORS.txt deleted file mode 100644 index 73cea1e8a5..0000000000 --- a/vendor/github.com/pion/srtp/v2/AUTHORS.txt +++ /dev/null @@ -1,37 +0,0 @@ -# Thank you to everyone that made Pion possible. If you are interested in contributing -# we would love to have you https://github.com/pion/webrtc/wiki/Contributing -# -# This file is auto generated, using git to list all individuals contributors. -# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting -adamroach -Adrian Cable -Agniva De Sarker -Antoine Baché -Atsushi Watanabe -backkem -chenkaiC4 -Chris Hiszpanski -cnderrauber -cszdlt -Hugo Arregui -Jerko Steiner -Juliusz Chroboczek -Luke Curley -Luke Curley -Max Hawkins -mission-liao -Novel Corpse -OrlandoCo -Patryk -Patryk Rogalski -Sean DuBois -Sean DuBois -SeongGyu Park -Steffen -Steffen Vogel -Tobias Fridén -Woodrow Douglass -Yutaka Takeda - -# List of contributors not appearing in Git history - diff --git a/vendor/github.com/pion/srtp/v2/.gitignore b/vendor/github.com/pion/srtp/v3/.gitignore similarity index 100% rename from vendor/github.com/pion/srtp/v2/.gitignore rename to vendor/github.com/pion/srtp/v3/.gitignore diff --git a/vendor/github.com/pion/srtp/v3/.golangci.yml b/vendor/github.com/pion/srtp/v3/.golangci.yml new file mode 100644 index 0000000000..a3235bec28 --- /dev/null +++ b/vendor/github.com/pion/srtp/v3/.golangci.yml @@ -0,0 +1,125 @@ +# SPDX-FileCopyrightText: 2023 The Pion community +# SPDX-License-Identifier: MIT + +run: + timeout: 5m + +linters-settings: + govet: + enable: + - shadow + misspell: + locale: US + exhaustive: + default-signifies-exhaustive: true + gomodguard: + blocked: + modules: + - github.com/pkg/errors: + recommendations: + - errors + forbidigo: + forbid: + - ^fmt.Print(f|ln)?$ + - ^log.(Panic|Fatal|Print)(f|ln)?$ + - ^os.Exit$ + - ^panic$ + - ^print(ln)?$ + +linters: + enable: + - asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers + - bidichk # Checks for dangerous unicode character sequences + - bodyclose # checks whether HTTP response body is closed successfully + - contextcheck # check the function whether use a non-inherited context + - decorder # check declaration order and count of types, constants, variables and functions + - dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) + - dupl # Tool for code clone detection + - durationcheck # check for two durations multiplied together + - errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases + - errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and optionally reports occations, where the check for the returned error can be omitted. + - errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. + - errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13. + - exhaustive # check exhaustiveness of enum switch statements + - exportloopref # checks for pointers to enclosing loop variables + - forbidigo # Forbids identifiers + - forcetypeassert # finds forced type assertions + - gci # Gci control golang package import order and make it always deterministic. + - gochecknoglobals # Checks that no globals are present in Go code + - gochecknoinits # Checks that no init functions are present in Go code + - gocognit # Computes and checks the cognitive complexity of functions + - goconst # Finds repeated strings that could be replaced by a constant + - gocritic # The most opinionated Go source code linter + - godox # Tool for detection of FIXME, TODO and other comment keywords + - err113 # Golang linter to check the errors handling expressions + - gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification + - gofumpt # Gofumpt checks whether code was gofumpt-ed. + - goheader # Checks is file header matches to pattern + - goimports # Goimports does everything that gofmt does. Additionally it checks unused imports + - gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. + - gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. + - goprintffuncname # Checks that printf-like functions are named with `f` at the end + - gosec # Inspects source code for security problems + - gosimple # Linter for Go source code that specializes in simplifying a code + - govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string + - grouper # An analyzer to analyze expression groups. + - importas # Enforces consistent import aliases + - ineffassign # Detects when assignments to existing variables are not used + - misspell # Finds commonly misspelled English words in comments + - nilerr # Finds the code that returns nil even if it checks that the error is not nil. + - nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. + - noctx # noctx finds sending http request without context.Context + - predeclared # find code that shadows one of Go's predeclared identifiers + - revive # golint replacement, finds style mistakes + - staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks + - stylecheck # Stylecheck is a replacement for golint + - tagliatelle # Checks the struct tags. + - tenv # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17 + - tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes + - typecheck # Like the front-end of a Go compiler, parses and type-checks Go code + - unconvert # Remove unnecessary type conversions + - unparam # Reports unused function parameters + - unused # Checks Go code for unused constants, variables, functions and types + - wastedassign # wastedassign finds wasted assignment statements + - whitespace # Tool for detection of leading and trailing whitespace + disable: + - depguard # Go linter that checks if package imports are in a list of acceptable packages + - containedctx # containedctx is a linter that detects struct contained context.Context field + - cyclop # checks function and package cyclomatic complexity + - funlen # Tool for detection of long functions + - gocyclo # Computes and checks the cyclomatic complexity of functions + - godot # Check if comments end in a period + - gomnd # An analyzer to detect magic numbers. + - ireturn # Accept Interfaces, Return Concrete Types + - lll # Reports long lines + - maintidx # maintidx measures the maintainability index of each function. + - makezero # Finds slice declarations with non-zero initial length + - nakedret # Finds naked returns in functions greater than a specified function length + - nestif # Reports deeply nested if statements + - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity + - nolintlint # Reports ill-formed or insufficient nolint directives + - paralleltest # paralleltest detects missing usage of t.Parallel() method in your Go test + - prealloc # Finds slice declarations that could potentially be preallocated + - promlinter # Check Prometheus metrics naming via promlint + - rowserrcheck # checks whether Err of rows is checked successfully + - sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed. + - testpackage # linter that makes you use a separate _test package + - thelper # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers + - varnamelen # checks that the length of a variable's name matches its scope + - wrapcheck # Checks that errors returned from external packages are wrapped + - wsl # Whitespace Linter - Forces you to use empty lines! + +issues: + exclude-use-default: false + exclude-dirs-use-default: false + exclude-rules: + # Allow complex tests and examples, better to be self contained + - path: (examples|main\.go|_test\.go) + linters: + - forbidigo + - gocognit + + # Allow forbidden identifiers in CLI commands + - path: cmd + linters: + - forbidigo diff --git a/vendor/github.com/pion/srtp/v2/.goreleaser.yml b/vendor/github.com/pion/srtp/v3/.goreleaser.yml similarity index 100% rename from vendor/github.com/pion/srtp/v2/.goreleaser.yml rename to vendor/github.com/pion/srtp/v3/.goreleaser.yml diff --git a/vendor/github.com/pion/srtp/v2/LICENSE b/vendor/github.com/pion/srtp/v3/LICENSE similarity index 100% rename from vendor/github.com/pion/srtp/v2/LICENSE rename to vendor/github.com/pion/srtp/v3/LICENSE diff --git a/vendor/github.com/pion/srtp/v2/README.md b/vendor/github.com/pion/srtp/v3/README.md similarity index 97% rename from vendor/github.com/pion/srtp/v2/README.md rename to vendor/github.com/pion/srtp/v3/README.md index d0e94e7a9b..d6fdbd0d36 100644 --- a/vendor/github.com/pion/srtp/v2/README.md +++ b/vendor/github.com/pion/srtp/v3/README.md @@ -29,7 +29,7 @@ We are always looking to support **your projects**. Please reach out if you have If you need commercial support or don't want to use public methods you can contact us at [team@pion.ly](mailto:team@pion.ly) ### Contributing -Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible: [AUTHORS.txt](./AUTHORS.txt) +Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible ### License MIT License - see [LICENSE](LICENSE) for full text diff --git a/vendor/github.com/pion/srtp/v2/codecov.yml b/vendor/github.com/pion/srtp/v3/codecov.yml similarity index 100% rename from vendor/github.com/pion/srtp/v2/codecov.yml rename to vendor/github.com/pion/srtp/v3/codecov.yml diff --git a/vendor/github.com/pion/srtp/v2/context.go b/vendor/github.com/pion/srtp/v3/context.go similarity index 99% rename from vendor/github.com/pion/srtp/v2/context.go rename to vendor/github.com/pion/srtp/v3/context.go index ffed38fabb..cb2ed56a77 100644 --- a/vendor/github.com/pion/srtp/v2/context.go +++ b/vendor/github.com/pion/srtp/v3/context.go @@ -7,7 +7,7 @@ import ( "bytes" "fmt" - "github.com/pion/transport/v2/replaydetector" + "github.com/pion/transport/v3/replaydetector" ) const ( diff --git a/vendor/github.com/pion/srtp/v2/crypto.go b/vendor/github.com/pion/srtp/v3/crypto.go similarity index 68% rename from vendor/github.com/pion/srtp/v2/crypto.go rename to vendor/github.com/pion/srtp/v3/crypto.go index 9696e8f2cb..3f19130173 100644 --- a/vendor/github.com/pion/srtp/v2/crypto.go +++ b/vendor/github.com/pion/srtp/v3/crypto.go @@ -5,8 +5,9 @@ package srtp import ( "crypto/cipher" + "sync" - "github.com/pion/transport/v2/utils/xor" + "github.com/pion/transport/v3/utils/xor" ) // incrementCTR increments a big-endian integer of arbitrary size. @@ -19,6 +20,12 @@ func incrementCTR(ctr []byte) { } } +var xorBufferPool = sync.Pool{ // nolint:gochecknoglobals + New: func() interface{} { + return make([]byte, 1500) + }, +} + // xorBytesCTR performs CTR encryption and decryption. // It is equivalent to cipher.NewCTR followed by XORKeyStream. func xorBytesCTR(block cipher.Block, iv []byte, dst, src []byte) error { @@ -26,10 +33,17 @@ func xorBytesCTR(block cipher.Block, iv []byte, dst, src []byte) error { return errBadIVLength } - ctr := make([]byte, len(iv)) + xorBuf := xorBufferPool.Get() + defer xorBufferPool.Put(xorBuf) + buffer, ok := xorBuf.([]byte) + if !ok { + return errFailedTypeAssertion + } + + ctr := buffer[:len(iv)] copy(ctr, iv) bs := block.BlockSize() - stream := make([]byte, bs) + stream := buffer[len(iv) : len(iv)+bs] i := 0 for i < len(src) { diff --git a/vendor/github.com/pion/srtp/v2/errors.go b/vendor/github.com/pion/srtp/v3/errors.go similarity index 100% rename from vendor/github.com/pion/srtp/v2/errors.go rename to vendor/github.com/pion/srtp/v3/errors.go diff --git a/vendor/github.com/pion/srtp/v2/key_derivation.go b/vendor/github.com/pion/srtp/v3/key_derivation.go similarity index 100% rename from vendor/github.com/pion/srtp/v2/key_derivation.go rename to vendor/github.com/pion/srtp/v3/key_derivation.go diff --git a/vendor/github.com/pion/srtp/v2/keying.go b/vendor/github.com/pion/srtp/v3/keying.go similarity index 100% rename from vendor/github.com/pion/srtp/v2/keying.go rename to vendor/github.com/pion/srtp/v3/keying.go diff --git a/vendor/github.com/pion/srtp/v2/option.go b/vendor/github.com/pion/srtp/v3/option.go similarity index 95% rename from vendor/github.com/pion/srtp/v2/option.go rename to vendor/github.com/pion/srtp/v3/option.go index 708274fae0..dac0bcf1da 100644 --- a/vendor/github.com/pion/srtp/v2/option.go +++ b/vendor/github.com/pion/srtp/v3/option.go @@ -4,7 +4,7 @@ package srtp import ( - "github.com/pion/transport/v2/replaydetector" + "github.com/pion/transport/v3/replaydetector" ) // ContextOption represents option of Context using the functional options pattern. @@ -68,8 +68,8 @@ func SRTCPReplayDetectorFactory(fn func() replaydetector.ReplayDetector) Context type nopReplayDetector struct{} -func (s *nopReplayDetector) Check(uint64) (func(), bool) { - return func() {}, true +func (s *nopReplayDetector) Check(uint64) (func() bool, bool) { + return func() bool { return true }, true } // MasterKeyIndicator sets RTP/RTCP MKI for the initial master key. Array passed as an argument will be diff --git a/vendor/github.com/pion/srtp/v2/protection_profile.go b/vendor/github.com/pion/srtp/v3/protection_profile.go similarity index 100% rename from vendor/github.com/pion/srtp/v2/protection_profile.go rename to vendor/github.com/pion/srtp/v3/protection_profile.go diff --git a/vendor/github.com/pion/srtp/v2/renovate.json b/vendor/github.com/pion/srtp/v3/renovate.json similarity index 100% rename from vendor/github.com/pion/srtp/v2/renovate.json rename to vendor/github.com/pion/srtp/v3/renovate.json diff --git a/vendor/github.com/pion/srtp/v2/session.go b/vendor/github.com/pion/srtp/v3/session.go similarity index 98% rename from vendor/github.com/pion/srtp/v2/session.go rename to vendor/github.com/pion/srtp/v3/session.go index 2e1f4fe3f1..cc4f600957 100644 --- a/vendor/github.com/pion/srtp/v2/session.go +++ b/vendor/github.com/pion/srtp/v3/session.go @@ -11,7 +11,7 @@ import ( "time" "github.com/pion/logging" - "github.com/pion/transport/v2/packetio" + "github.com/pion/transport/v3/packetio" ) type streamSession interface { diff --git a/vendor/github.com/pion/srtp/v2/session_srtcp.go b/vendor/github.com/pion/srtp/v3/session_srtcp.go similarity index 100% rename from vendor/github.com/pion/srtp/v2/session_srtcp.go rename to vendor/github.com/pion/srtp/v3/session_srtcp.go diff --git a/vendor/github.com/pion/srtp/v2/session_srtp.go b/vendor/github.com/pion/srtp/v3/session_srtp.go similarity index 100% rename from vendor/github.com/pion/srtp/v2/session_srtp.go rename to vendor/github.com/pion/srtp/v3/session_srtp.go diff --git a/vendor/github.com/pion/srtp/v2/srtcp.go b/vendor/github.com/pion/srtp/v3/srtcp.go similarity index 100% rename from vendor/github.com/pion/srtp/v2/srtcp.go rename to vendor/github.com/pion/srtp/v3/srtcp.go diff --git a/vendor/github.com/pion/srtp/v2/srtp.go b/vendor/github.com/pion/srtp/v3/srtp.go similarity index 100% rename from vendor/github.com/pion/srtp/v2/srtp.go rename to vendor/github.com/pion/srtp/v3/srtp.go diff --git a/vendor/github.com/pion/srtp/v2/srtp_cipher.go b/vendor/github.com/pion/srtp/v3/srtp_cipher.go similarity index 100% rename from vendor/github.com/pion/srtp/v2/srtp_cipher.go rename to vendor/github.com/pion/srtp/v3/srtp_cipher.go diff --git a/vendor/github.com/pion/srtp/v2/srtp_cipher_aead_aes_gcm.go b/vendor/github.com/pion/srtp/v3/srtp_cipher_aead_aes_gcm.go similarity index 96% rename from vendor/github.com/pion/srtp/v2/srtp_cipher_aead_aes_gcm.go rename to vendor/github.com/pion/srtp/v3/srtp_cipher_aead_aes_gcm.go index ac50c39bb4..64f890fa9f 100644 --- a/vendor/github.com/pion/srtp/v2/srtp_cipher_aead_aes_gcm.go +++ b/vendor/github.com/pion/srtp/v3/srtp_cipher_aead_aes_gcm.go @@ -130,14 +130,14 @@ func (s *srtpCipherAeadAesGcm) decryptRTP(dst, ciphertext []byte, header *rtp.He if _, err := s.srtpCipher.Open( dst[headerLen:headerLen], iv[:], ciphertext[headerLen:nEnd], ciphertext[:headerLen], ); err != nil { - return nil, fmt.Errorf("%s: %s", ErrFailedToVerifyAuthTag, err) + return nil, fmt.Errorf("%w: %w", ErrFailedToVerifyAuthTag, err) } } else { nDataEnd := nEnd - authTagLen if _, err := s.srtpCipher.Open( nil, iv[:], ciphertext[nDataEnd:nEnd], ciphertext[:nDataEnd], ); err != nil { - return nil, fmt.Errorf("%s: %w", ErrFailedToVerifyAuthTag, err) + return nil, fmt.Errorf("%w: %w", ErrFailedToVerifyAuthTag, err) } copy(dst[headerLen:], ciphertext[headerLen:nDataEnd]) } @@ -198,7 +198,7 @@ func (s *srtpCipherAeadAesGcm) decryptRTCP(dst, encrypted []byte, srtcpIndex, ss if isEncrypted { aad := s.rtcpAdditionalAuthenticatedData(encrypted, srtcpIndex) if _, err := s.srtcpCipher.Open(dst[8:8], iv[:], encrypted[8:aadPos], aad[:]); err != nil { - return nil, fmt.Errorf("%s: %w", ErrFailedToVerifyAuthTag, err) + return nil, fmt.Errorf("%w: %w", ErrFailedToVerifyAuthTag, err) } } else { // Prepare AAD for received packet. @@ -208,7 +208,7 @@ func (s *srtpCipherAeadAesGcm) decryptRTCP(dst, encrypted []byte, srtcpIndex, ss copy(aad[dataEnd:], encrypted[aadPos:aadPos+4]) // Verify the auth tag. if _, err := s.srtcpCipher.Open(nil, iv[:], encrypted[dataEnd:aadPos], aad); err != nil { - return nil, fmt.Errorf("%s: %w", ErrFailedToVerifyAuthTag, err) + return nil, fmt.Errorf("%w: %w", ErrFailedToVerifyAuthTag, err) } // Copy the unencrypted payload. copy(dst[8:], encrypted[8:dataEnd]) diff --git a/vendor/github.com/pion/srtp/v2/srtp_cipher_aes_cm_hmac_sha1.go b/vendor/github.com/pion/srtp/v3/srtp_cipher_aes_cm_hmac_sha1.go similarity index 100% rename from vendor/github.com/pion/srtp/v2/srtp_cipher_aes_cm_hmac_sha1.go rename to vendor/github.com/pion/srtp/v3/srtp_cipher_aes_cm_hmac_sha1.go diff --git a/vendor/github.com/pion/srtp/v2/stream.go b/vendor/github.com/pion/srtp/v3/stream.go similarity index 100% rename from vendor/github.com/pion/srtp/v2/stream.go rename to vendor/github.com/pion/srtp/v3/stream.go diff --git a/vendor/github.com/pion/srtp/v2/stream_srtcp.go b/vendor/github.com/pion/srtp/v3/stream_srtcp.go similarity index 98% rename from vendor/github.com/pion/srtp/v2/stream_srtcp.go rename to vendor/github.com/pion/srtp/v3/stream_srtcp.go index 08d36dca5a..dc71c40f38 100644 --- a/vendor/github.com/pion/srtp/v2/stream_srtcp.go +++ b/vendor/github.com/pion/srtp/v3/stream_srtcp.go @@ -10,7 +10,7 @@ import ( "time" "github.com/pion/rtcp" - "github.com/pion/transport/v2/packetio" + "github.com/pion/transport/v3/packetio" ) // Limit the buffer size to 100KB diff --git a/vendor/github.com/pion/srtp/v2/stream_srtp.go b/vendor/github.com/pion/srtp/v3/stream_srtp.go similarity index 98% rename from vendor/github.com/pion/srtp/v2/stream_srtp.go rename to vendor/github.com/pion/srtp/v3/stream_srtp.go index 8589700824..cad0a38c1a 100644 --- a/vendor/github.com/pion/srtp/v2/stream_srtp.go +++ b/vendor/github.com/pion/srtp/v3/stream_srtp.go @@ -10,7 +10,7 @@ import ( "time" "github.com/pion/rtp" - "github.com/pion/transport/v2/packetio" + "github.com/pion/transport/v3/packetio" ) // Limit the buffer size to 1MB diff --git a/vendor/github.com/pion/srtp/v2/util.go b/vendor/github.com/pion/srtp/v3/util.go similarity index 100% rename from vendor/github.com/pion/srtp/v2/util.go rename to vendor/github.com/pion/srtp/v3/util.go diff --git a/vendor/github.com/pion/stun/AUTHORS.txt b/vendor/github.com/pion/stun/AUTHORS.txt deleted file mode 100644 index 3c3d9e00fb..0000000000 --- a/vendor/github.com/pion/stun/AUTHORS.txt +++ /dev/null @@ -1,40 +0,0 @@ -# Thank you to everyone that made Pion possible. If you are interested in contributing -# we would love to have you https://github.com/pion/webrtc/wiki/Contributing -# -# This file is auto generated, using git to list all individuals contributors. -# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting -Adam Kiss -Aleksandr Razumov -Aleksandr Razumov -Atsushi Watanabe -backkem -Cecylia Bocovich -Christian Muehlhaeuser -David-dp- -ernado -ernado -fossabot -Frank Dietrich -Hugo Arregui -Jerry Tao -jinleileiking -John Bradley -Juliusz Chroboczek -Maanas Royy -Moises Marangoni -Raphael Randschau -Sean DuBois -Sean DuBois -Sean DuBois -songjiayang -Steffen Vogel -Vladislav Yarmak -Will LE -Y.Horie -Yutaka Takeda -ZHENK - -# List of contributors not appearing in Git history -Aliaksandr Valialkin -The IETF Trust -The gortc project diff --git a/vendor/github.com/pion/stun/.gitignore b/vendor/github.com/pion/stun/v3/.gitignore similarity index 100% rename from vendor/github.com/pion/stun/.gitignore rename to vendor/github.com/pion/stun/v3/.gitignore diff --git a/vendor/github.com/pion/dtls/v2/.golangci.yml b/vendor/github.com/pion/stun/v3/.golangci.yml similarity index 95% rename from vendor/github.com/pion/dtls/v2/.golangci.yml rename to vendor/github.com/pion/stun/v3/.golangci.yml index 4e3eddf429..e06de4d3c0 100644 --- a/vendor/github.com/pion/dtls/v2/.golangci.yml +++ b/vendor/github.com/pion/stun/v3/.golangci.yml @@ -3,7 +3,8 @@ linters-settings: govet: - check-shadowing: true + enable: + - shadow misspell: locale: US exhaustive: @@ -29,7 +30,6 @@ linters: - bodyclose # checks whether HTTP response body is closed successfully - contextcheck # check the function whether use a non-inherited context - decorder # check declaration order and count of types, constants, variables and functions - - depguard # Go linter that checks if package imports are in a list of acceptable packages - dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) - dupl # Tool for code clone detection - durationcheck # check for two durations multiplied together @@ -63,7 +63,6 @@ linters: - importas # Enforces consistent import aliases - ineffassign # Detects when assignments to existing variables are not used - misspell # Finds commonly misspelled English words in comments - - nakedret # Finds naked returns in functions greater than a specified function length - nilerr # Finds the code that returns nil even if it checks that the error is not nil. - nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. - noctx # noctx finds sending http request without context.Context @@ -81,6 +80,7 @@ linters: - wastedassign # wastedassign finds wasted assignment statements - whitespace # Tool for detection of leading and trailing whitespace disable: + - depguard # Go linter that checks if package imports are in a list of acceptable packages - containedctx # containedctx is a linter that detects struct contained context.Context field - cyclop # checks function and package cyclomatic complexity - exhaustivestruct # Checks if all struct's fields are initialized @@ -94,6 +94,7 @@ linters: - maintidx # maintidx measures the maintainability index of each function. - makezero # Finds slice declarations with non-zero initial length - maligned # Tool to detect Go structs that would take less memory if their fields were sorted + - nakedret # Finds naked returns in functions greater than a specified function length - nestif # Reports deeply nested if statements - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity - nolintlint # Reports ill-formed or insufficient nolint directives @@ -110,28 +111,15 @@ linters: issues: exclude-use-default: false + exclude-dirs-use-default: false exclude-rules: - # Allow complex tests, better to be self contained - - path: _test\.go + # Allow complex tests and examples, better to be self contained + - path: (examples|main\.go|_test\.go) linters: - - gocognit - forbidigo - - # Allow complex main function in examples - - path: examples - text: "of func `main` is high" - linters: - gocognit - - # Allow forbidden identifiers in examples - - path: examples - linters: - - forbidigo # Allow forbidden identifiers in CLI commands - path: cmd linters: - forbidigo - -run: - skip-dirs-use-default: false diff --git a/vendor/github.com/pion/stun/.goreleaser.yml b/vendor/github.com/pion/stun/v3/.goreleaser.yml similarity index 100% rename from vendor/github.com/pion/stun/.goreleaser.yml rename to vendor/github.com/pion/stun/v3/.goreleaser.yml diff --git a/vendor/github.com/pion/stun/LICENSE b/vendor/github.com/pion/stun/v3/LICENSE similarity index 100% rename from vendor/github.com/pion/stun/LICENSE rename to vendor/github.com/pion/stun/v3/LICENSE diff --git a/vendor/github.com/pion/stun/Makefile b/vendor/github.com/pion/stun/v3/Makefile similarity index 96% rename from vendor/github.com/pion/stun/Makefile rename to vendor/github.com/pion/stun/v3/Makefile index ebfcd3394e..eaaefa5c6a 100644 --- a/vendor/github.com/pion/stun/Makefile +++ b/vendor/github.com/pion/stun/v3/Makefile @@ -32,8 +32,6 @@ install: test-integration: @cd e2e && bash ./test.sh prepush: test lint test-integration -check-api: - @cd api && bash ./check.sh test: @./go.test.sh clean: diff --git a/vendor/github.com/pion/stun/README.md b/vendor/github.com/pion/stun/v3/README.md similarity index 99% rename from vendor/github.com/pion/stun/README.md rename to vendor/github.com/pion/stun/v3/README.md index fe1b28ffb2..f0661e58b6 100644 --- a/vendor/github.com/pion/stun/README.md +++ b/vendor/github.com/pion/stun/v3/README.md @@ -180,7 +180,7 @@ We are always looking to support **your projects**. Please reach out if you have If you need commercial support or don't want to use public methods you can contact us at [team@pion.ly](mailto:team@pion.ly) ### Contributing -Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible: [AUTHORS.txt](./AUTHORS.txt) +Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible ### License MIT License - see [LICENSE](LICENSE) for full text diff --git a/vendor/github.com/pion/stun/addr.go b/vendor/github.com/pion/stun/v3/addr.go similarity index 100% rename from vendor/github.com/pion/stun/addr.go rename to vendor/github.com/pion/stun/v3/addr.go diff --git a/vendor/github.com/pion/stun/agent.go b/vendor/github.com/pion/stun/v3/agent.go similarity index 99% rename from vendor/github.com/pion/stun/agent.go rename to vendor/github.com/pion/stun/v3/agent.go index f03efa3c0a..bc160c864b 100644 --- a/vendor/github.com/pion/stun/agent.go +++ b/vendor/github.com/pion/stun/v3/agent.go @@ -11,7 +11,7 @@ import ( // NoopHandler just discards any event. func NoopHandler() Handler { - return func(e Event) {} + return func(Event) {} } // NewAgent initializes and returns new Agent with provided handler. diff --git a/vendor/github.com/pion/stun/attributes.go b/vendor/github.com/pion/stun/v3/attributes.go similarity index 100% rename from vendor/github.com/pion/stun/attributes.go rename to vendor/github.com/pion/stun/v3/attributes.go diff --git a/vendor/github.com/pion/stun/attributes_debug.go b/vendor/github.com/pion/stun/v3/attributes_debug.go similarity index 100% rename from vendor/github.com/pion/stun/attributes_debug.go rename to vendor/github.com/pion/stun/v3/attributes_debug.go diff --git a/vendor/github.com/pion/stun/checks.go b/vendor/github.com/pion/stun/v3/checks.go similarity index 96% rename from vendor/github.com/pion/stun/checks.go rename to vendor/github.com/pion/stun/v3/checks.go index 6b678a06b5..db90a5a73e 100644 --- a/vendor/github.com/pion/stun/checks.go +++ b/vendor/github.com/pion/stun/v3/checks.go @@ -9,7 +9,7 @@ package stun import ( "errors" - "github.com/pion/stun/internal/hmac" + "github.com/pion/stun/v3/internal/hmac" ) // CheckSize returns ErrAttrSizeInvalid if got is not equal to expected. diff --git a/vendor/github.com/pion/stun/checks_debug.go b/vendor/github.com/pion/stun/v3/checks_debug.go similarity index 96% rename from vendor/github.com/pion/stun/checks_debug.go rename to vendor/github.com/pion/stun/v3/checks_debug.go index 0b5c67c83b..fe236c7f8c 100644 --- a/vendor/github.com/pion/stun/checks_debug.go +++ b/vendor/github.com/pion/stun/v3/checks_debug.go @@ -6,7 +6,7 @@ package stun -import "github.com/pion/stun/internal/hmac" +import "github.com/pion/stun/v3/internal/hmac" // CheckSize returns *AttrLengthError if got is not equal to expected. func CheckSize(a AttrType, got, expected int) error { diff --git a/vendor/github.com/pion/stun/client.go b/vendor/github.com/pion/stun/v3/client.go similarity index 97% rename from vendor/github.com/pion/stun/client.go rename to vendor/github.com/pion/stun/v3/client.go index 5d02e51dc8..24d3fafeb9 100644 --- a/vendor/github.com/pion/stun/client.go +++ b/vendor/github.com/pion/stun/v3/client.go @@ -16,9 +16,9 @@ import ( "sync/atomic" "time" - "github.com/pion/dtls/v2" - "github.com/pion/transport/v2" - "github.com/pion/transport/v2/stdnet" + "github.com/pion/dtls/v3" + "github.com/pion/transport/v3" + "github.com/pion/transport/v3/stdnet" ) // ErrUnsupportedURI is an error thrown if the user passes an unsupported STUN or TURN URI @@ -78,12 +78,17 @@ func DialURI(uri *URI, cfg *DialConfig) (*Client, error) { dtlsCfg := cfg.DTLSConfig // Copy dtlsCfg.ServerName = uri.Host - udpConn, err := nw.Dial("udp", addr) + udpAddr, err := net.ResolveUDPAddr("udp", addr) + if err != nil { + return nil, fmt.Errorf("failed to resolve UDPAddr: %w", err) + } + + udpConn, err := nw.DialUDP("udp", nil, udpAddr) if err != nil { return nil, fmt.Errorf("failed to dial: %w", err) } - if conn, err = dtls.Client(udpConn, &dtlsCfg); err != nil { + if conn, err = dtls.Client(udpConn, udpConn.RemoteAddr(), &dtlsCfg); err != nil { return nil, fmt.Errorf("failed to connect to '%s': %w", addr, err) } diff --git a/vendor/github.com/pion/stun/codecov.yml b/vendor/github.com/pion/stun/v3/codecov.yml similarity index 100% rename from vendor/github.com/pion/stun/codecov.yml rename to vendor/github.com/pion/stun/v3/codecov.yml diff --git a/vendor/github.com/pion/stun/errorcode.go b/vendor/github.com/pion/stun/v3/errorcode.go similarity index 100% rename from vendor/github.com/pion/stun/errorcode.go rename to vendor/github.com/pion/stun/v3/errorcode.go diff --git a/vendor/github.com/pion/stun/errors.go b/vendor/github.com/pion/stun/v3/errors.go similarity index 100% rename from vendor/github.com/pion/stun/errors.go rename to vendor/github.com/pion/stun/v3/errors.go diff --git a/vendor/github.com/pion/stun/fingerprint.go b/vendor/github.com/pion/stun/v3/fingerprint.go similarity index 100% rename from vendor/github.com/pion/stun/fingerprint.go rename to vendor/github.com/pion/stun/v3/fingerprint.go diff --git a/vendor/github.com/pion/stun/fingerprint_debug.go b/vendor/github.com/pion/stun/v3/fingerprint_debug.go similarity index 100% rename from vendor/github.com/pion/stun/fingerprint_debug.go rename to vendor/github.com/pion/stun/v3/fingerprint_debug.go diff --git a/vendor/github.com/pion/stun/helpers.go b/vendor/github.com/pion/stun/v3/helpers.go similarity index 100% rename from vendor/github.com/pion/stun/helpers.go rename to vendor/github.com/pion/stun/v3/helpers.go diff --git a/vendor/github.com/pion/stun/integrity.go b/vendor/github.com/pion/stun/v3/integrity.go similarity index 98% rename from vendor/github.com/pion/stun/integrity.go rename to vendor/github.com/pion/stun/v3/integrity.go index 0fee0b0759..29f688934f 100644 --- a/vendor/github.com/pion/stun/integrity.go +++ b/vendor/github.com/pion/stun/v3/integrity.go @@ -10,7 +10,7 @@ import ( //nolint:gci "fmt" "strings" - "github.com/pion/stun/internal/hmac" + "github.com/pion/stun/v3/internal/hmac" ) // separator for credentials. diff --git a/vendor/github.com/pion/stun/integrity_debug.go b/vendor/github.com/pion/stun/v3/integrity_debug.go similarity index 100% rename from vendor/github.com/pion/stun/integrity_debug.go rename to vendor/github.com/pion/stun/v3/integrity_debug.go diff --git a/vendor/github.com/pion/stun/internal/hmac/hmac.go b/vendor/github.com/pion/stun/v3/internal/hmac/hmac.go similarity index 100% rename from vendor/github.com/pion/stun/internal/hmac/hmac.go rename to vendor/github.com/pion/stun/v3/internal/hmac/hmac.go diff --git a/vendor/github.com/pion/stun/internal/hmac/pool.go b/vendor/github.com/pion/stun/v3/internal/hmac/pool.go similarity index 100% rename from vendor/github.com/pion/stun/internal/hmac/pool.go rename to vendor/github.com/pion/stun/v3/internal/hmac/pool.go diff --git a/vendor/github.com/pion/stun/internal/hmac/vendor.sh b/vendor/github.com/pion/stun/v3/internal/hmac/vendor.sh similarity index 100% rename from vendor/github.com/pion/stun/internal/hmac/vendor.sh rename to vendor/github.com/pion/stun/v3/internal/hmac/vendor.sh diff --git a/vendor/github.com/pion/stun/message.go b/vendor/github.com/pion/stun/v3/message.go similarity index 100% rename from vendor/github.com/pion/stun/message.go rename to vendor/github.com/pion/stun/v3/message.go diff --git a/vendor/github.com/pion/stun/renovate.json b/vendor/github.com/pion/stun/v3/renovate.json similarity index 100% rename from vendor/github.com/pion/stun/renovate.json rename to vendor/github.com/pion/stun/v3/renovate.json diff --git a/vendor/github.com/pion/stun/stun.go b/vendor/github.com/pion/stun/v3/stun.go similarity index 100% rename from vendor/github.com/pion/stun/stun.go rename to vendor/github.com/pion/stun/v3/stun.go diff --git a/vendor/github.com/pion/stun/textattrs.go b/vendor/github.com/pion/stun/v3/textattrs.go similarity index 100% rename from vendor/github.com/pion/stun/textattrs.go rename to vendor/github.com/pion/stun/v3/textattrs.go diff --git a/vendor/github.com/pion/stun/uattrs.go b/vendor/github.com/pion/stun/v3/uattrs.go similarity index 100% rename from vendor/github.com/pion/stun/uattrs.go rename to vendor/github.com/pion/stun/v3/uattrs.go diff --git a/vendor/github.com/pion/stun/uri.go b/vendor/github.com/pion/stun/v3/uri.go similarity index 100% rename from vendor/github.com/pion/stun/uri.go rename to vendor/github.com/pion/stun/v3/uri.go diff --git a/vendor/github.com/pion/stun/xoraddr.go b/vendor/github.com/pion/stun/v3/xoraddr.go similarity index 98% rename from vendor/github.com/pion/stun/xoraddr.go rename to vendor/github.com/pion/stun/v3/xoraddr.go index fc423be869..2c5a9548f0 100644 --- a/vendor/github.com/pion/stun/xoraddr.go +++ b/vendor/github.com/pion/stun/v3/xoraddr.go @@ -10,7 +10,7 @@ import ( "net" "strconv" - "github.com/pion/transport/v2/utils/xor" + "github.com/pion/transport/v3/utils/xor" ) const ( diff --git a/vendor/github.com/pion/transport/v2/.golangci.yml b/vendor/github.com/pion/transport/v2/.golangci.yml deleted file mode 100644 index 4e3eddf429..0000000000 --- a/vendor/github.com/pion/transport/v2/.golangci.yml +++ /dev/null @@ -1,137 +0,0 @@ -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -linters-settings: - govet: - check-shadowing: true - misspell: - locale: US - exhaustive: - default-signifies-exhaustive: true - gomodguard: - blocked: - modules: - - github.com/pkg/errors: - recommendations: - - errors - forbidigo: - forbid: - - ^fmt.Print(f|ln)?$ - - ^log.(Panic|Fatal|Print)(f|ln)?$ - - ^os.Exit$ - - ^panic$ - - ^print(ln)?$ - -linters: - enable: - - asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers - - bidichk # Checks for dangerous unicode character sequences - - bodyclose # checks whether HTTP response body is closed successfully - - contextcheck # check the function whether use a non-inherited context - - decorder # check declaration order and count of types, constants, variables and functions - - depguard # Go linter that checks if package imports are in a list of acceptable packages - - dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) - - dupl # Tool for code clone detection - - durationcheck # check for two durations multiplied together - - errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases - - errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and optionally reports occations, where the check for the returned error can be omitted. - - errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. - - errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13. - - exhaustive # check exhaustiveness of enum switch statements - - exportloopref # checks for pointers to enclosing loop variables - - forbidigo # Forbids identifiers - - forcetypeassert # finds forced type assertions - - gci # Gci control golang package import order and make it always deterministic. - - gochecknoglobals # Checks that no globals are present in Go code - - gochecknoinits # Checks that no init functions are present in Go code - - gocognit # Computes and checks the cognitive complexity of functions - - goconst # Finds repeated strings that could be replaced by a constant - - gocritic # The most opinionated Go source code linter - - godox # Tool for detection of FIXME, TODO and other comment keywords - - goerr113 # Golang linter to check the errors handling expressions - - gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification - - gofumpt # Gofumpt checks whether code was gofumpt-ed. - - goheader # Checks is file header matches to pattern - - goimports # Goimports does everything that gofmt does. Additionally it checks unused imports - - gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. - - gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. - - goprintffuncname # Checks that printf-like functions are named with `f` at the end - - gosec # Inspects source code for security problems - - gosimple # Linter for Go source code that specializes in simplifying a code - - govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string - - grouper # An analyzer to analyze expression groups. - - importas # Enforces consistent import aliases - - ineffassign # Detects when assignments to existing variables are not used - - misspell # Finds commonly misspelled English words in comments - - nakedret # Finds naked returns in functions greater than a specified function length - - nilerr # Finds the code that returns nil even if it checks that the error is not nil. - - nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. - - noctx # noctx finds sending http request without context.Context - - predeclared # find code that shadows one of Go's predeclared identifiers - - revive # golint replacement, finds style mistakes - - staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks - - stylecheck # Stylecheck is a replacement for golint - - tagliatelle # Checks the struct tags. - - tenv # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17 - - tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes - - typecheck # Like the front-end of a Go compiler, parses and type-checks Go code - - unconvert # Remove unnecessary type conversions - - unparam # Reports unused function parameters - - unused # Checks Go code for unused constants, variables, functions and types - - wastedassign # wastedassign finds wasted assignment statements - - whitespace # Tool for detection of leading and trailing whitespace - disable: - - containedctx # containedctx is a linter that detects struct contained context.Context field - - cyclop # checks function and package cyclomatic complexity - - exhaustivestruct # Checks if all struct's fields are initialized - - funlen # Tool for detection of long functions - - gocyclo # Computes and checks the cyclomatic complexity of functions - - godot # Check if comments end in a period - - gomnd # An analyzer to detect magic numbers. - - ifshort # Checks that your code uses short syntax for if-statements whenever possible - - ireturn # Accept Interfaces, Return Concrete Types - - lll # Reports long lines - - maintidx # maintidx measures the maintainability index of each function. - - makezero # Finds slice declarations with non-zero initial length - - maligned # Tool to detect Go structs that would take less memory if their fields were sorted - - nestif # Reports deeply nested if statements - - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity - - nolintlint # Reports ill-formed or insufficient nolint directives - - paralleltest # paralleltest detects missing usage of t.Parallel() method in your Go test - - prealloc # Finds slice declarations that could potentially be preallocated - - promlinter # Check Prometheus metrics naming via promlint - - rowserrcheck # checks whether Err of rows is checked successfully - - sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed. - - testpackage # linter that makes you use a separate _test package - - thelper # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers - - varnamelen # checks that the length of a variable's name matches its scope - - wrapcheck # Checks that errors returned from external packages are wrapped - - wsl # Whitespace Linter - Forces you to use empty lines! - -issues: - exclude-use-default: false - exclude-rules: - # Allow complex tests, better to be self contained - - path: _test\.go - linters: - - gocognit - - forbidigo - - # Allow complex main function in examples - - path: examples - text: "of func `main` is high" - linters: - - gocognit - - # Allow forbidden identifiers in examples - - path: examples - linters: - - forbidigo - - # Allow forbidden identifiers in CLI commands - - path: cmd - linters: - - forbidigo - -run: - skip-dirs-use-default: false diff --git a/vendor/github.com/pion/transport/v2/AUTHORS.txt b/vendor/github.com/pion/transport/v2/AUTHORS.txt deleted file mode 100644 index b595c41c5a..0000000000 --- a/vendor/github.com/pion/transport/v2/AUTHORS.txt +++ /dev/null @@ -1,29 +0,0 @@ -# Thank you to everyone that made Pion possible. If you are interested in contributing -# we would love to have you https://github.com/pion/webrtc/wiki/Contributing -# -# This file is auto generated, using git to list all individuals contributors. -# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting -Adrian Cable -Atsushi Watanabe -backkem -cnderrauber -Daniel Mangum -Hugo Arregui -Jeremiah Millay -Jozef Kralik -Juliusz Chroboczek -Luke Curley -Mathis Engelbart -OrlandoCo -Sean DuBois -Sean DuBois -Sean DuBois -Sean DuBois -Steffen Vogel -Winlin -Woodrow Douglass -Yutaka Takeda -ZHENK - -# List of contributors not appearing in Git history - diff --git a/vendor/github.com/pion/transport/v2/udp/batchconn.go b/vendor/github.com/pion/transport/v2/udp/batchconn.go deleted file mode 100644 index 54bdab65fe..0000000000 --- a/vendor/github.com/pion/transport/v2/udp/batchconn.go +++ /dev/null @@ -1,170 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package udp - -import ( - "io" - "net" - "runtime" - "sync" - "sync/atomic" - "time" - - "golang.org/x/net/ipv4" - "golang.org/x/net/ipv6" -) - -// BatchWriter represents conn can write messages in batch -type BatchWriter interface { - WriteBatch(ms []ipv4.Message, flags int) (int, error) -} - -// BatchReader represents conn can read messages in batch -type BatchReader interface { - ReadBatch(msg []ipv4.Message, flags int) (int, error) -} - -// BatchPacketConn represents conn can read/write messages in batch -type BatchPacketConn interface { - BatchWriter - BatchReader - io.Closer -} - -// BatchConn uses ipv4/v6.NewPacketConn to wrap a net.PacketConn to write/read messages in batch, -// only available in linux. In other platform, it will use single Write/Read as same as net.Conn. -type BatchConn struct { - net.PacketConn - - batchConn BatchPacketConn - - batchWriteMutex sync.Mutex - batchWriteMessages []ipv4.Message - batchWritePos int - batchWriteLast time.Time - - batchWriteSize int - batchWriteInterval time.Duration - - closed int32 -} - -// NewBatchConn creates a *BatchConn from net.PacketConn with batch configs. -func NewBatchConn(conn net.PacketConn, batchWriteSize int, batchWriteInterval time.Duration) *BatchConn { - bc := &BatchConn{ - PacketConn: conn, - batchWriteLast: time.Now(), - batchWriteInterval: batchWriteInterval, - batchWriteSize: batchWriteSize, - batchWriteMessages: make([]ipv4.Message, batchWriteSize), - } - for i := range bc.batchWriteMessages { - bc.batchWriteMessages[i].Buffers = [][]byte{make([]byte, sendMTU)} - } - - // batch write only supports linux - if runtime.GOOS == "linux" { - if pc4 := ipv4.NewPacketConn(conn); pc4 != nil { - bc.batchConn = pc4 - } else if pc6 := ipv6.NewPacketConn(conn); pc6 != nil { - bc.batchConn = pc6 - } - } - - if bc.batchConn != nil { - go func() { - writeTicker := time.NewTicker(batchWriteInterval / 2) - defer writeTicker.Stop() - for atomic.LoadInt32(&bc.closed) != 1 { - <-writeTicker.C - bc.batchWriteMutex.Lock() - if bc.batchWritePos > 0 && time.Since(bc.batchWriteLast) >= bc.batchWriteInterval { - _ = bc.flush() - } - bc.batchWriteMutex.Unlock() - } - }() - } - - return bc -} - -// Close batchConn and the underlying PacketConn -func (c *BatchConn) Close() error { - atomic.StoreInt32(&c.closed, 1) - c.batchWriteMutex.Lock() - if c.batchWritePos > 0 { - _ = c.flush() - } - c.batchWriteMutex.Unlock() - if c.batchConn != nil { - return c.batchConn.Close() - } - return c.PacketConn.Close() -} - -// WriteTo write message to an UDPAddr, addr should be nil if it is a connected socket. -func (c *BatchConn) WriteTo(b []byte, addr net.Addr) (int, error) { - if c.batchConn == nil { - return c.PacketConn.WriteTo(b, addr) - } - return c.enqueueMessage(b, addr) -} - -func (c *BatchConn) enqueueMessage(buf []byte, raddr net.Addr) (int, error) { - var err error - c.batchWriteMutex.Lock() - defer c.batchWriteMutex.Unlock() - - msg := &c.batchWriteMessages[c.batchWritePos] - // reset buffers - msg.Buffers = msg.Buffers[:1] - msg.Buffers[0] = msg.Buffers[0][:cap(msg.Buffers[0])] - - c.batchWritePos++ - if raddr != nil { - msg.Addr = raddr - } - if n := copy(msg.Buffers[0], buf); n < len(buf) { - extraBuffer := make([]byte, len(buf)-n) - copy(extraBuffer, buf[n:]) - msg.Buffers = append(msg.Buffers, extraBuffer) - } else { - msg.Buffers[0] = msg.Buffers[0][:n] - } - if c.batchWritePos == c.batchWriteSize { - err = c.flush() - } - return len(buf), err -} - -// ReadBatch reads messages in batch, return length of message readed and error. -func (c *BatchConn) ReadBatch(msgs []ipv4.Message, flags int) (int, error) { - if c.batchConn == nil { - n, addr, err := c.PacketConn.ReadFrom(msgs[0].Buffers[0]) - if err == nil { - msgs[0].N = n - msgs[0].Addr = addr - return 1, nil - } - return 0, err - } - return c.batchConn.ReadBatch(msgs, flags) -} - -func (c *BatchConn) flush() error { - var writeErr error - var txN int - for txN < c.batchWritePos { - n, err := c.batchConn.WriteBatch(c.batchWriteMessages[txN:c.batchWritePos], 0) - if err != nil { - writeErr = err - break - } - txN += n - } - c.batchWritePos = 0 - c.batchWriteLast = time.Now() - return writeErr -} diff --git a/vendor/github.com/pion/transport/v2/udp/conn.go b/vendor/github.com/pion/transport/v2/udp/conn.go deleted file mode 100644 index c2f257eaf4..0000000000 --- a/vendor/github.com/pion/transport/v2/udp/conn.go +++ /dev/null @@ -1,406 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package udp provides a connection-oriented listener over a UDP PacketConn -package udp - -import ( - "context" - "errors" - "net" - "sync" - "sync/atomic" - "time" - - "github.com/pion/logging" - "github.com/pion/transport/v2/deadline" - "github.com/pion/transport/v2/packetio" - "golang.org/x/net/ipv4" -) - -const ( - receiveMTU = 8192 - sendMTU = 1500 - defaultListenBacklog = 128 // same as Linux default -) - -// Typed errors -var ( - ErrClosedListener = errors.New("udp: listener closed") - ErrListenQueueExceeded = errors.New("udp: listen queue exceeded") - ErrInvalidBatchConfig = errors.New("udp: invalid batch config") -) - -// listener augments a connection-oriented Listener over a UDP PacketConn -type listener struct { - pConn net.PacketConn - - readBatchSize int - - accepting atomic.Value // bool - acceptCh chan *Conn - doneCh chan struct{} - doneOnce sync.Once - acceptFilter func([]byte) bool - - connLock sync.Mutex - conns map[string]*Conn - connWG *sync.WaitGroup - - readWG sync.WaitGroup - errClose atomic.Value // error - - readDoneCh chan struct{} - errRead atomic.Value // error - - logger logging.LeveledLogger -} - -// Accept waits for and returns the next connection to the listener. -func (l *listener) Accept() (net.Conn, error) { - select { - case c := <-l.acceptCh: - l.connWG.Add(1) - return c, nil - - case <-l.readDoneCh: - err, _ := l.errRead.Load().(error) - return nil, err - - case <-l.doneCh: - return nil, ErrClosedListener - } -} - -// Close closes the listener. -// Any blocked Accept operations will be unblocked and return errors. -func (l *listener) Close() error { - var err error - l.doneOnce.Do(func() { - l.accepting.Store(false) - close(l.doneCh) - - l.connLock.Lock() - // Close unaccepted connections - lclose: - for { - select { - case c := <-l.acceptCh: - close(c.doneCh) - delete(l.conns, c.rAddr.String()) - - default: - break lclose - } - } - nConns := len(l.conns) - l.connLock.Unlock() - - l.connWG.Done() - - if nConns == 0 { - // Wait if this is the final connection - l.readWG.Wait() - if errClose, ok := l.errClose.Load().(error); ok { - err = errClose - } - } else { - err = nil - } - }) - - return err -} - -// Addr returns the listener's network address. -func (l *listener) Addr() net.Addr { - return l.pConn.LocalAddr() -} - -// BatchIOConfig indicates config to batch read/write packets, -// it will use ReadBatch/WriteBatch to improve throughput for UDP. -type BatchIOConfig struct { - Enable bool - // ReadBatchSize indicates the maximum number of packets to be read in one batch, a batch size less than 2 means - // disable read batch. - ReadBatchSize int - // WriteBatchSize indicates the maximum number of packets to be written in one batch - WriteBatchSize int - // WriteBatchInterval indicates the maximum interval to wait before writing packets in one batch - // small interval will reduce latency/jitter, but increase the io count. - WriteBatchInterval time.Duration -} - -// ListenConfig stores options for listening to an address. -type ListenConfig struct { - // Backlog defines the maximum length of the queue of pending - // connections. It is equivalent of the backlog argument of - // POSIX listen function. - // If a connection request arrives when the queue is full, - // the request will be silently discarded, unlike TCP. - // Set zero to use default value 128 which is same as Linux default. - Backlog int - - // AcceptFilter determines whether the new conn should be made for - // the incoming packet. If not set, any packet creates new conn. - AcceptFilter func([]byte) bool - - // ReadBufferSize sets the size of the operating system's - // receive buffer associated with the listener. - ReadBufferSize int - - // WriteBufferSize sets the size of the operating system's - // send buffer associated with the connection. - WriteBufferSize int - - Batch BatchIOConfig - - LoggerFactory logging.LoggerFactory -} - -// Listen creates a new listener based on the ListenConfig. -func (lc *ListenConfig) Listen(network string, laddr *net.UDPAddr) (net.Listener, error) { - if lc.Backlog == 0 { - lc.Backlog = defaultListenBacklog - } - - if lc.Batch.Enable && (lc.Batch.WriteBatchSize <= 0 || lc.Batch.WriteBatchInterval <= 0) { - return nil, ErrInvalidBatchConfig - } - - conn, err := net.ListenUDP(network, laddr) - if err != nil { - return nil, err - } - - if lc.ReadBufferSize > 0 { - _ = conn.SetReadBuffer(lc.ReadBufferSize) - } - if lc.WriteBufferSize > 0 { - _ = conn.SetWriteBuffer(lc.WriteBufferSize) - } - - loggerFactory := lc.LoggerFactory - if loggerFactory == nil { - loggerFactory = logging.NewDefaultLoggerFactory() - } - - logger := loggerFactory.NewLogger("transport") - - l := &listener{ - pConn: conn, - acceptCh: make(chan *Conn, lc.Backlog), - conns: make(map[string]*Conn), - doneCh: make(chan struct{}), - acceptFilter: lc.AcceptFilter, - connWG: &sync.WaitGroup{}, - readDoneCh: make(chan struct{}), - logger: logger, - } - - if lc.Batch.Enable { - l.pConn = NewBatchConn(conn, lc.Batch.WriteBatchSize, lc.Batch.WriteBatchInterval) - l.readBatchSize = lc.Batch.ReadBatchSize - } - - l.accepting.Store(true) - l.connWG.Add(1) - l.readWG.Add(2) // wait readLoop and Close execution routine - - go l.readLoop() - go func() { - l.connWG.Wait() - if err := l.pConn.Close(); err != nil { - l.errClose.Store(err) - } - l.readWG.Done() - }() - - return l, nil -} - -// Listen creates a new listener using default ListenConfig. -func Listen(network string, laddr *net.UDPAddr) (net.Listener, error) { - return (&ListenConfig{}).Listen(network, laddr) -} - -// readLoop has to tasks: -// 1. Dispatching incoming packets to the correct Conn. -// It can therefore not be ended until all Conns are closed. -// 2. Creating a new Conn when receiving from a new remote. -func (l *listener) readLoop() { - defer l.readWG.Done() - defer close(l.readDoneCh) - - if br, ok := l.pConn.(BatchReader); ok && l.readBatchSize > 1 { - l.readBatch(br) - } else { - l.read() - } -} - -func (l *listener) readBatch(br BatchReader) { - msgs := make([]ipv4.Message, l.readBatchSize) - for i := range msgs { - msg := &msgs[i] - msg.Buffers = [][]byte{make([]byte, receiveMTU)} - msg.OOB = make([]byte, 40) - } - for { - n, err := br.ReadBatch(msgs, 0) - if err != nil { - l.errRead.Store(err) - return - } - for i := 0; i < n; i++ { - l.dispatchMsg(msgs[i].Addr, msgs[i].Buffers[0][:msgs[i].N]) - } - } -} - -func (l *listener) read() { - buf := make([]byte, receiveMTU) - for { - n, raddr, err := l.pConn.ReadFrom(buf) - if err != nil { - l.errRead.Store(err) - l.logger.Tracef("error reading from connection err=%v", err) - return - } - l.dispatchMsg(raddr, buf[:n]) - } -} - -func (l *listener) dispatchMsg(addr net.Addr, buf []byte) { - conn, ok, err := l.getConn(addr, buf) - if err != nil { - return - } - if ok { - _, err := conn.buffer.Write(buf) - if err != nil { - l.logger.Tracef("error dispatching message addr=%v err=%v", addr, err) - } - } -} - -func (l *listener) getConn(raddr net.Addr, buf []byte) (*Conn, bool, error) { - l.connLock.Lock() - defer l.connLock.Unlock() - conn, ok := l.conns[raddr.String()] - if !ok { - if isAccepting, ok := l.accepting.Load().(bool); !isAccepting || !ok { - return nil, false, ErrClosedListener - } - if l.acceptFilter != nil { - if !l.acceptFilter(buf) { - return nil, false, nil - } - } - conn = l.newConn(raddr) - select { - case l.acceptCh <- conn: - l.conns[raddr.String()] = conn - default: - return nil, false, ErrListenQueueExceeded - } - } - return conn, true, nil -} - -// Conn augments a connection-oriented connection over a UDP PacketConn -type Conn struct { - listener *listener - - rAddr net.Addr - - buffer *packetio.Buffer - - doneCh chan struct{} - doneOnce sync.Once - - writeDeadline *deadline.Deadline -} - -func (l *listener) newConn(rAddr net.Addr) *Conn { - return &Conn{ - listener: l, - rAddr: rAddr, - buffer: packetio.NewBuffer(), - doneCh: make(chan struct{}), - writeDeadline: deadline.New(), - } -} - -// Read reads from c into p -func (c *Conn) Read(p []byte) (int, error) { - return c.buffer.Read(p) -} - -// Write writes len(p) bytes from p to the DTLS connection -func (c *Conn) Write(p []byte) (n int, err error) { - select { - case <-c.writeDeadline.Done(): - return 0, context.DeadlineExceeded - default: - } - return c.listener.pConn.WriteTo(p, c.rAddr) -} - -// Close closes the conn and releases any Read calls -func (c *Conn) Close() error { - var err error - c.doneOnce.Do(func() { - c.listener.connWG.Done() - close(c.doneCh) - c.listener.connLock.Lock() - delete(c.listener.conns, c.rAddr.String()) - nConns := len(c.listener.conns) - c.listener.connLock.Unlock() - - if isAccepting, ok := c.listener.accepting.Load().(bool); nConns == 0 && !isAccepting && ok { - // Wait if this is the final connection - c.listener.readWG.Wait() - if errClose, ok := c.listener.errClose.Load().(error); ok { - err = errClose - } - } else { - err = nil - } - - if errBuf := c.buffer.Close(); errBuf != nil && err == nil { - err = errBuf - } - }) - - return err -} - -// LocalAddr implements net.Conn.LocalAddr -func (c *Conn) LocalAddr() net.Addr { - return c.listener.pConn.LocalAddr() -} - -// RemoteAddr implements net.Conn.RemoteAddr -func (c *Conn) RemoteAddr() net.Addr { - return c.rAddr -} - -// SetDeadline implements net.Conn.SetDeadline -func (c *Conn) SetDeadline(t time.Time) error { - c.writeDeadline.Set(t) - return c.SetReadDeadline(t) -} - -// SetReadDeadline implements net.Conn.SetDeadline -func (c *Conn) SetReadDeadline(t time.Time) error { - return c.buffer.SetReadDeadline(t) -} - -// SetWriteDeadline implements net.Conn.SetDeadline -func (c *Conn) SetWriteDeadline(t time.Time) error { - c.writeDeadline.Set(t) - // Write deadline of underlying connection should not be changed - // since the connection can be shared. - return nil -} diff --git a/vendor/github.com/pion/transport/v2/utils/xor/xor_amd64.go b/vendor/github.com/pion/transport/v2/utils/xor/xor_amd64.go deleted file mode 100644 index ded8e0d353..0000000000 --- a/vendor/github.com/pion/transport/v2/utils/xor/xor_amd64.go +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-FileCopyrightText: 2018 The Go Authors. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause - -//go:build !gccgo -// +build !gccgo - -// Package xor provides utility functions used by other Pion -// packages. AMD64 arch. -package xor - -// XorBytes xors the bytes in a and b. The destination should have enough -// space, otherwise xorBytes will panic. Returns the number of bytes xor'd. -// -//revive:disable-next-line -func XorBytes(dst, a, b []byte) int { - n := len(a) - if len(b) < n { - n = len(b) - } - if n == 0 { - return 0 - } - _ = dst[n-1] - xorBytesSSE2(&dst[0], &a[0], &b[0], n) // amd64 must have SSE2 - return n -} - -//go:noescape -func xorBytesSSE2(dst, a, b *byte, n int) diff --git a/vendor/github.com/pion/transport/v2/utils/xor/xor_amd64.s b/vendor/github.com/pion/transport/v2/utils/xor/xor_amd64.s deleted file mode 100644 index f66ac95a21..0000000000 --- a/vendor/github.com/pion/transport/v2/utils/xor/xor_amd64.s +++ /dev/null @@ -1,56 +0,0 @@ -// SPDX-FileCopyrightText: 2018 The Go Authors. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause - -// go:build !gccgo -// +build !gccgo - -#include "textflag.h" - -// func xorBytesSSE2(dst, a, b *byte, n int) -TEXT ·xorBytesSSE2(SB), NOSPLIT, $0 - MOVQ dst+0(FP), BX - MOVQ a+8(FP), SI - MOVQ b+16(FP), CX - MOVQ n+24(FP), DX - TESTQ $15, DX // AND 15 & len, if not zero jump to not_aligned. - JNZ not_aligned - -aligned: - MOVQ $0, AX // position in slices - -loop16b: - MOVOU (SI)(AX*1), X0 // XOR 16byte forwards. - MOVOU (CX)(AX*1), X1 - PXOR X1, X0 - MOVOU X0, (BX)(AX*1) - ADDQ $16, AX - CMPQ DX, AX - JNE loop16b - RET - -loop_1b: - SUBQ $1, DX // XOR 1byte backwards. - MOVB (SI)(DX*1), DI - MOVB (CX)(DX*1), AX - XORB AX, DI - MOVB DI, (BX)(DX*1) - TESTQ $7, DX // AND 7 & len, if not zero jump to loop_1b. - JNZ loop_1b - CMPQ DX, $0 // if len is 0, ret. - JE ret - TESTQ $15, DX // AND 15 & len, if zero jump to aligned. - JZ aligned - -not_aligned: - TESTQ $7, DX // AND $7 & len, if not zero jump to loop_1b. - JNE loop_1b - SUBQ $8, DX // XOR 8bytes backwards. - MOVQ (SI)(DX*1), DI - MOVQ (CX)(DX*1), AX - XORQ AX, DI - MOVQ DI, (BX)(DX*1) - CMPQ DX, $16 // if len is greater or equal 16 here, it must be aligned. - JGE aligned - -ret: - RET diff --git a/vendor/github.com/pion/transport/v2/utils/xor/xor_arm64.go b/vendor/github.com/pion/transport/v2/utils/xor/xor_arm64.go deleted file mode 100644 index 7002ab7c9a..0000000000 --- a/vendor/github.com/pion/transport/v2/utils/xor/xor_arm64.go +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-FileCopyrightText: 2020 The Go Authors. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause - -//go:build !gccgo -// +build !gccgo - -// Package xor provides utility functions used by other Pion -// packages. ARM64 arch. -package xor - -// XorBytes xors the bytes in a and b. The destination should have enough -// space, otherwise xorBytes will panic. Returns the number of bytes xor'd. -// -//revive:disable-next-line -func XorBytes(dst, a, b []byte) int { - n := len(a) - if len(b) < n { - n = len(b) - } - if n == 0 { - return 0 - } - // make sure dst has enough space - _ = dst[n-1] - - xorBytesARM64(&dst[0], &a[0], &b[0], n) - return n -} - -//go:noescape -func xorBytesARM64(dst, a, b *byte, n int) diff --git a/vendor/github.com/pion/transport/v2/utils/xor/xor_arm64.s b/vendor/github.com/pion/transport/v2/utils/xor/xor_arm64.s deleted file mode 100644 index 0b82d09923..0000000000 --- a/vendor/github.com/pion/transport/v2/utils/xor/xor_arm64.s +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-FileCopyrightText: 2020 The Go Authors. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause - -//go:build !gccgo -// +build !gccgo - -#include "textflag.h" - -// func xorBytesARM64(dst, a, b *byte, n int) -TEXT ·xorBytesARM64(SB), NOSPLIT|NOFRAME, $0 - MOVD dst+0(FP), R0 - MOVD a+8(FP), R1 - MOVD b+16(FP), R2 - MOVD n+24(FP), R3 - CMP $64, R3 - BLT tail -loop_64: - VLD1.P 64(R1), [V0.B16, V1.B16, V2.B16, V3.B16] - VLD1.P 64(R2), [V4.B16, V5.B16, V6.B16, V7.B16] - VEOR V0.B16, V4.B16, V4.B16 - VEOR V1.B16, V5.B16, V5.B16 - VEOR V2.B16, V6.B16, V6.B16 - VEOR V3.B16, V7.B16, V7.B16 - VST1.P [V4.B16, V5.B16, V6.B16, V7.B16], 64(R0) - SUBS $64, R3 - CMP $64, R3 - BGE loop_64 -tail: - // quick end - CBZ R3, end - TBZ $5, R3, less_than32 - VLD1.P 32(R1), [V0.B16, V1.B16] - VLD1.P 32(R2), [V2.B16, V3.B16] - VEOR V0.B16, V2.B16, V2.B16 - VEOR V1.B16, V3.B16, V3.B16 - VST1.P [V2.B16, V3.B16], 32(R0) -less_than32: - TBZ $4, R3, less_than16 - LDP.P 16(R1), (R11, R12) - LDP.P 16(R2), (R13, R14) - EOR R11, R13, R13 - EOR R12, R14, R14 - STP.P (R13, R14), 16(R0) -less_than16: - TBZ $3, R3, less_than8 - MOVD.P 8(R1), R11 - MOVD.P 8(R2), R12 - EOR R11, R12, R12 - MOVD.P R12, 8(R0) -less_than8: - TBZ $2, R3, less_than4 - MOVWU.P 4(R1), R13 - MOVWU.P 4(R2), R14 - EORW R13, R14, R14 - MOVWU.P R14, 4(R0) -less_than4: - TBZ $1, R3, less_than2 - MOVHU.P 2(R1), R15 - MOVHU.P 2(R2), R16 - EORW R15, R16, R16 - MOVHU.P R16, 2(R0) -less_than2: - TBZ $0, R3, end - MOVBU (R1), R17 - MOVBU (R2), R19 - EORW R17, R19, R19 - MOVBU R19, (R0) -end: - RET diff --git a/vendor/github.com/pion/transport/v2/utils/xor/xor_ppc64x.go b/vendor/github.com/pion/transport/v2/utils/xor/xor_ppc64x.go deleted file mode 100644 index bcc5926c44..0000000000 --- a/vendor/github.com/pion/transport/v2/utils/xor/xor_ppc64x.go +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-FileCopyrightText: 2018 The Go Authors. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause - -//go:build (ppc64 && !gccgo) || (ppc64le && !gccgo) -// +build ppc64,!gccgo ppc64le,!gccgo - -// Package xor provides utility functions used by other Pion -// packages. PPC64 arch. -package xor - -// XorBytes xors the bytes in a and b. The destination should have enough -// space, otherwise xorBytes will panic. Returns the number of bytes xor'd. -// -//revive:disable-next-line -func XorBytes(dst, a, b []byte) int { - n := len(a) - if len(b) < n { - n = len(b) - } - if n == 0 { - return 0 - } - _ = dst[n-1] - xorBytesVSX(&dst[0], &a[0], &b[0], n) - return n -} - -//go:noescape -func xorBytesVSX(dst, a, b *byte, n int) diff --git a/vendor/github.com/pion/transport/v2/utils/xor/xor_ppc64x.s b/vendor/github.com/pion/transport/v2/utils/xor/xor_ppc64x.s deleted file mode 100644 index 22763535fd..0000000000 --- a/vendor/github.com/pion/transport/v2/utils/xor/xor_ppc64x.s +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-FileCopyrightText: 2018 The Go Authors. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause - -//go:build (ppc64 && !gccgo) || (ppc64le && !gccgo) -//+build ppc64,!gccgo ppc64le,!gccgo - -#include "textflag.h" - -// func xorBytesVSX(dst, a, b *byte, n int) -TEXT ·xorBytesVSX(SB), NOSPLIT, $0 - MOVD dst+0(FP), R3 // R3 = dst - MOVD a+8(FP), R4 // R4 = a - MOVD b+16(FP), R5 // R5 = b - MOVD n+24(FP), R6 // R6 = n - - CMPU R6, $32, CR7 // Check if n ≥ 32 bytes - MOVD R0, R8 // R8 = index - CMPU R6, $8, CR6 // Check if 8 ≤ n < 32 bytes - BLT CR6, small // Smaller than 8 - BLT CR7, xor16 // Case for 16 ≤ n < 32 bytes - - // Case for n ≥ 32 bytes -preloop32: - SRD $5, R6, R7 // Setup loop counter - MOVD R7, CTR - MOVD $16, R10 - ANDCC $31, R6, R9 // Check for tailing bytes for later -loop32: - LXVD2X (R4)(R8), VS32 // VS32 = a[i,...,i+15] - LXVD2X (R4)(R10), VS34 - LXVD2X (R5)(R8), VS33 // VS33 = b[i,...,i+15] - LXVD2X (R5)(R10), VS35 - XXLXOR VS32, VS33, VS32 // VS34 = a[] ^ b[] - XXLXOR VS34, VS35, VS34 - STXVD2X VS32, (R3)(R8) // Store to dst - STXVD2X VS34, (R3)(R10) - ADD $32, R8 // Update index - ADD $32, R10 - BC 16, 0, loop32 // bdnz loop16 - - BEQ CR0, done - - MOVD R9, R6 - CMP R6, $8 - BLT small -xor16: - CMP R6, $16 - BLT xor8 - LXVD2X (R4)(R8), VS32 - LXVD2X (R5)(R8), VS33 - XXLXOR VS32, VS33, VS32 - STXVD2X VS32, (R3)(R8) - ADD $16, R8 - ADD $-16, R6 - CMP R6, $8 - BLT small -xor8: - // Case for 8 ≤ n < 16 bytes - MOVD (R4)(R8), R14 // R14 = a[i,...,i+7] - MOVD (R5)(R8), R15 // R15 = b[i,...,i+7] - XOR R14, R15, R16 // R16 = a[] ^ b[] - SUB $8, R6 // n = n - 8 - MOVD R16, (R3)(R8) // Store to dst - ADD $8, R8 - - // Check if we're finished - CMP R6, R0 - BGT small - RET - - // Case for n < 8 bytes and tailing bytes from the - // previous cases. -small: - CMP R6, R0 - BEQ done - MOVD R6, CTR // Setup loop counter - -loop: - MOVBZ (R4)(R8), R14 // R14 = a[i] - MOVBZ (R5)(R8), R15 // R15 = b[i] - XOR R14, R15, R16 // R16 = a[i] ^ b[i] - MOVB R16, (R3)(R8) // Store to dst - ADD $1, R8 - BC 16, 0, loop // bdnz loop - -done: - RET diff --git a/vendor/github.com/pion/transport/v2/.gitignore b/vendor/github.com/pion/transport/v3/.gitignore similarity index 100% rename from vendor/github.com/pion/transport/v2/.gitignore rename to vendor/github.com/pion/transport/v3/.gitignore diff --git a/vendor/github.com/pion/stun/.golangci.yml b/vendor/github.com/pion/transport/v3/.golangci.yml similarity index 95% rename from vendor/github.com/pion/stun/.golangci.yml rename to vendor/github.com/pion/transport/v3/.golangci.yml index 4e3eddf429..e06de4d3c0 100644 --- a/vendor/github.com/pion/stun/.golangci.yml +++ b/vendor/github.com/pion/transport/v3/.golangci.yml @@ -3,7 +3,8 @@ linters-settings: govet: - check-shadowing: true + enable: + - shadow misspell: locale: US exhaustive: @@ -29,7 +30,6 @@ linters: - bodyclose # checks whether HTTP response body is closed successfully - contextcheck # check the function whether use a non-inherited context - decorder # check declaration order and count of types, constants, variables and functions - - depguard # Go linter that checks if package imports are in a list of acceptable packages - dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) - dupl # Tool for code clone detection - durationcheck # check for two durations multiplied together @@ -63,7 +63,6 @@ linters: - importas # Enforces consistent import aliases - ineffassign # Detects when assignments to existing variables are not used - misspell # Finds commonly misspelled English words in comments - - nakedret # Finds naked returns in functions greater than a specified function length - nilerr # Finds the code that returns nil even if it checks that the error is not nil. - nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. - noctx # noctx finds sending http request without context.Context @@ -81,6 +80,7 @@ linters: - wastedassign # wastedassign finds wasted assignment statements - whitespace # Tool for detection of leading and trailing whitespace disable: + - depguard # Go linter that checks if package imports are in a list of acceptable packages - containedctx # containedctx is a linter that detects struct contained context.Context field - cyclop # checks function and package cyclomatic complexity - exhaustivestruct # Checks if all struct's fields are initialized @@ -94,6 +94,7 @@ linters: - maintidx # maintidx measures the maintainability index of each function. - makezero # Finds slice declarations with non-zero initial length - maligned # Tool to detect Go structs that would take less memory if their fields were sorted + - nakedret # Finds naked returns in functions greater than a specified function length - nestif # Reports deeply nested if statements - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity - nolintlint # Reports ill-formed or insufficient nolint directives @@ -110,28 +111,15 @@ linters: issues: exclude-use-default: false + exclude-dirs-use-default: false exclude-rules: - # Allow complex tests, better to be self contained - - path: _test\.go + # Allow complex tests and examples, better to be self contained + - path: (examples|main\.go|_test\.go) linters: - - gocognit - forbidigo - - # Allow complex main function in examples - - path: examples - text: "of func `main` is high" - linters: - gocognit - - # Allow forbidden identifiers in examples - - path: examples - linters: - - forbidigo # Allow forbidden identifiers in CLI commands - path: cmd linters: - forbidigo - -run: - skip-dirs-use-default: false diff --git a/vendor/github.com/pion/transport/v2/.goreleaser.yml b/vendor/github.com/pion/transport/v3/.goreleaser.yml similarity index 100% rename from vendor/github.com/pion/transport/v2/.goreleaser.yml rename to vendor/github.com/pion/transport/v3/.goreleaser.yml diff --git a/vendor/github.com/pion/transport/v2/LICENSE b/vendor/github.com/pion/transport/v3/LICENSE similarity index 100% rename from vendor/github.com/pion/transport/v2/LICENSE rename to vendor/github.com/pion/transport/v3/LICENSE diff --git a/vendor/github.com/pion/transport/v2/README.md b/vendor/github.com/pion/transport/v3/README.md similarity index 97% rename from vendor/github.com/pion/transport/v2/README.md rename to vendor/github.com/pion/transport/v3/README.md index b604b104d7..c1045f39d5 100644 --- a/vendor/github.com/pion/transport/v2/README.md +++ b/vendor/github.com/pion/transport/v3/README.md @@ -28,7 +28,7 @@ We are always looking to support **your projects**. Please reach out if you have If you need commercial support or don't want to use public methods you can contact us at [team@pion.ly](mailto:team@pion.ly) ### Contributing -Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible: [AUTHORS.txt](./AUTHORS.txt) +Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible ### License MIT License - see [LICENSE](LICENSE) for full text diff --git a/vendor/github.com/pion/transport/v2/codecov.yml b/vendor/github.com/pion/transport/v3/codecov.yml similarity index 100% rename from vendor/github.com/pion/transport/v2/codecov.yml rename to vendor/github.com/pion/transport/v3/codecov.yml diff --git a/vendor/github.com/pion/transport/v2/deadline/deadline.go b/vendor/github.com/pion/transport/v3/deadline/deadline.go similarity index 100% rename from vendor/github.com/pion/transport/v2/deadline/deadline.go rename to vendor/github.com/pion/transport/v3/deadline/deadline.go diff --git a/vendor/github.com/pion/transport/v2/deadline/timer.go b/vendor/github.com/pion/transport/v3/deadline/timer.go similarity index 100% rename from vendor/github.com/pion/transport/v2/deadline/timer.go rename to vendor/github.com/pion/transport/v3/deadline/timer.go diff --git a/vendor/github.com/pion/transport/v2/deadline/timer_generic.go b/vendor/github.com/pion/transport/v3/deadline/timer_generic.go similarity index 100% rename from vendor/github.com/pion/transport/v2/deadline/timer_generic.go rename to vendor/github.com/pion/transport/v3/deadline/timer_generic.go diff --git a/vendor/github.com/pion/transport/v2/deadline/timer_js.go b/vendor/github.com/pion/transport/v3/deadline/timer_js.go similarity index 100% rename from vendor/github.com/pion/transport/v2/deadline/timer_js.go rename to vendor/github.com/pion/transport/v3/deadline/timer_js.go diff --git a/vendor/github.com/pion/transport/v2/net.go b/vendor/github.com/pion/transport/v3/net.go similarity index 100% rename from vendor/github.com/pion/transport/v2/net.go rename to vendor/github.com/pion/transport/v3/net.go diff --git a/vendor/github.com/pion/transport/v2/connctx/connctx.go b/vendor/github.com/pion/transport/v3/netctx/conn.go similarity index 70% rename from vendor/github.com/pion/transport/v2/connctx/connctx.go rename to vendor/github.com/pion/transport/v3/netctx/conn.go index 4869b9c2e5..823107c7e0 100644 --- a/vendor/github.com/pion/transport/v2/connctx/connctx.go +++ b/vendor/github.com/pion/transport/v3/netctx/conn.go @@ -1,10 +1,8 @@ // SPDX-FileCopyrightText: 2023 The Pion community // SPDX-License-Identifier: MIT -// Package connctx wraps net.Conn using context.Context. -// -// Deprecated: use netctx instead. -package connctx +// Package netctx wraps common net interfaces using context.Context. +package netctx import ( "context" @@ -35,8 +33,8 @@ type ReadWriter interface { Writer } -// ConnCtx is a wrapper of net.Conn using context.Context. -type ConnCtx interface { +// Conn is a wrapper of net.Conn using context.Context. +type Conn interface { Reader Writer io.Closer @@ -45,7 +43,7 @@ type ConnCtx interface { Conn() net.Conn } -type connCtx struct { +type conn struct { nextConn net.Conn closed chan struct{} closeOnce sync.Once @@ -55,22 +53,24 @@ type connCtx struct { var veryOld = time.Unix(0, 1) //nolint:gochecknoglobals -// New creates a new ConnCtx wrapping given net.Conn. -func New(conn net.Conn) ConnCtx { - c := &connCtx{ - nextConn: conn, +// NewConn creates a new Conn wrapping given net.Conn. +func NewConn(netConn net.Conn) Conn { + c := &conn{ + nextConn: netConn, closed: make(chan struct{}), } return c } -func (c *connCtx) ReadContext(ctx context.Context, b []byte) (int, error) { +// ReadContext reads data from the connection. +// Unlike net.Conn.Read(), the provided context is used to control timeout. +func (c *conn) ReadContext(ctx context.Context, b []byte) (int, error) { c.readMu.Lock() defer c.readMu.Unlock() select { case <-c.closed: - return 0, io.EOF + return 0, net.ErrClosed default: } @@ -108,7 +108,9 @@ func (c *connCtx) ReadContext(ctx context.Context, b []byte) (int, error) { return n, err } -func (c *connCtx) WriteContext(ctx context.Context, b []byte) (int, error) { +// WriteContext writes data to the connection. +// Unlike net.Conn.Write(), the provided context is used to control timeout. +func (c *conn) WriteContext(ctx context.Context, b []byte) (int, error) { c.writeMu.Lock() defer c.writeMu.Unlock() @@ -152,7 +154,10 @@ func (c *connCtx) WriteContext(ctx context.Context, b []byte) (int, error) { return n, err } -func (c *connCtx) Close() error { +// Close closes the connection. +// Any blocked ReadContext or WriteContext operations will be unblocked and +// return errors. +func (c *conn) Close() error { err := c.nextConn.Close() c.closeOnce.Do(func() { c.writeMu.Lock() @@ -164,14 +169,17 @@ func (c *connCtx) Close() error { return err } -func (c *connCtx) LocalAddr() net.Addr { +// LocalAddr returns the local network address, if known. +func (c *conn) LocalAddr() net.Addr { return c.nextConn.LocalAddr() } -func (c *connCtx) RemoteAddr() net.Addr { +// LocalAddr returns the local network address, if known. +func (c *conn) RemoteAddr() net.Addr { return c.nextConn.RemoteAddr() } -func (c *connCtx) Conn() net.Conn { +// Conn returns the underlying net.Conn. +func (c *conn) Conn() net.Conn { return c.nextConn } diff --git a/vendor/github.com/pion/transport/v3/netctx/packetconn.go b/vendor/github.com/pion/transport/v3/netctx/packetconn.go new file mode 100644 index 0000000000..a4ce22d956 --- /dev/null +++ b/vendor/github.com/pion/transport/v3/netctx/packetconn.go @@ -0,0 +1,175 @@ +// SPDX-FileCopyrightText: 2023 The Pion community +// SPDX-License-Identifier: MIT + +package netctx + +import ( + "context" + "io" + "net" + "sync" + "sync/atomic" + "time" +) + +// ReaderFrom is an interface for context controlled packet reader. +type ReaderFrom interface { + ReadFromContext(context.Context, []byte) (int, net.Addr, error) +} + +// WriterTo is an interface for context controlled packet writer. +type WriterTo interface { + WriteToContext(context.Context, []byte, net.Addr) (int, error) +} + +// PacketConn is a wrapper of net.PacketConn using context.Context. +type PacketConn interface { + ReaderFrom + WriterTo + io.Closer + LocalAddr() net.Addr + Conn() net.PacketConn +} + +type packetConn struct { + nextConn net.PacketConn + closed chan struct{} + closeOnce sync.Once + readMu sync.Mutex + writeMu sync.Mutex +} + +// NewPacketConn creates a new PacketConn wrapping the given net.PacketConn. +func NewPacketConn(pconn net.PacketConn) PacketConn { + p := &packetConn{ + nextConn: pconn, + closed: make(chan struct{}), + } + return p +} + +// ReadFromContext reads a packet from the connection, +// copying the payload into p. It returns the number of +// bytes copied into p and the return address that +// was on the packet. +// It returns the number of bytes read (0 <= n <= len(p)) +// and any error encountered. Callers should always process +// the n > 0 bytes returned before considering the error err. +// Unlike net.PacketConn.ReadFrom(), the provided context is +// used to control timeout. +func (p *packetConn) ReadFromContext(ctx context.Context, b []byte) (int, net.Addr, error) { + p.readMu.Lock() + defer p.readMu.Unlock() + + select { + case <-p.closed: + return 0, nil, net.ErrClosed + default: + } + + done := make(chan struct{}) + var wg sync.WaitGroup + var errSetDeadline atomic.Value + wg.Add(1) + go func() { + defer wg.Done() + select { + case <-ctx.Done(): + // context canceled + if err := p.nextConn.SetReadDeadline(veryOld); err != nil { + errSetDeadline.Store(err) + return + } + <-done + if err := p.nextConn.SetReadDeadline(time.Time{}); err != nil { + errSetDeadline.Store(err) + } + case <-done: + } + }() + + n, raddr, err := p.nextConn.ReadFrom(b) + + close(done) + wg.Wait() + if e := ctx.Err(); e != nil && n == 0 { + err = e + } + if err2, ok := errSetDeadline.Load().(error); ok && err == nil && err2 != nil { + err = err2 + } + return n, raddr, err +} + +// WriteToContext writes a packet with payload p to addr. +// Unlike net.PacketConn.WriteTo(), the provided context +// is used to control timeout. +// On packet-oriented connections, write timeouts are rare. +func (p *packetConn) WriteToContext(ctx context.Context, b []byte, raddr net.Addr) (int, error) { + p.writeMu.Lock() + defer p.writeMu.Unlock() + + select { + case <-p.closed: + return 0, ErrClosing + default: + } + + done := make(chan struct{}) + var wg sync.WaitGroup + var errSetDeadline atomic.Value + wg.Add(1) + go func() { + defer wg.Done() + select { + case <-ctx.Done(): + // context canceled + if err := p.nextConn.SetWriteDeadline(veryOld); err != nil { + errSetDeadline.Store(err) + return + } + <-done + if err := p.nextConn.SetWriteDeadline(time.Time{}); err != nil { + errSetDeadline.Store(err) + } + case <-done: + } + }() + + n, err := p.nextConn.WriteTo(b, raddr) + + close(done) + wg.Wait() + if e := ctx.Err(); e != nil && n == 0 { + err = e + } + if err2, ok := errSetDeadline.Load().(error); ok && err == nil && err2 != nil { + err = err2 + } + return n, err +} + +// Close closes the connection. +// Any blocked ReadFromContext or WriteToContext operations will be unblocked +// and return errors. +func (p *packetConn) Close() error { + err := p.nextConn.Close() + p.closeOnce.Do(func() { + p.writeMu.Lock() + p.readMu.Lock() + close(p.closed) + p.readMu.Unlock() + p.writeMu.Unlock() + }) + return err +} + +// LocalAddr returns the local network address, if known. +func (p *packetConn) LocalAddr() net.Addr { + return p.nextConn.LocalAddr() +} + +// Conn returns the underlying net.PacketConn. +func (p *packetConn) Conn() net.PacketConn { + return p.nextConn +} diff --git a/vendor/github.com/pion/transport/v2/connctx/pipe.go b/vendor/github.com/pion/transport/v3/netctx/pipe.go similarity index 56% rename from vendor/github.com/pion/transport/v2/connctx/pipe.go rename to vendor/github.com/pion/transport/v3/netctx/pipe.go index 96b802e434..7deae668aa 100644 --- a/vendor/github.com/pion/transport/v2/connctx/pipe.go +++ b/vendor/github.com/pion/transport/v3/netctx/pipe.go @@ -1,14 +1,14 @@ // SPDX-FileCopyrightText: 2023 The Pion community // SPDX-License-Identifier: MIT -package connctx +package netctx import ( "net" ) -// Pipe creates piped pair of ConnCtx. -func Pipe() (ConnCtx, ConnCtx) { +// Pipe creates piped pair of Conn. +func Pipe() (Conn, Conn) { ca, cb := net.Pipe() - return New(ca), New(cb) + return NewConn(ca), NewConn(cb) } diff --git a/vendor/github.com/pion/transport/v2/packetio/buffer.go b/vendor/github.com/pion/transport/v3/packetio/buffer.go similarity index 98% rename from vendor/github.com/pion/transport/v2/packetio/buffer.go rename to vendor/github.com/pion/transport/v3/packetio/buffer.go index 9f91b04751..cdd39d77ce 100644 --- a/vendor/github.com/pion/transport/v2/packetio/buffer.go +++ b/vendor/github.com/pion/transport/v3/packetio/buffer.go @@ -10,7 +10,7 @@ import ( "sync" "time" - "github.com/pion/transport/v2/deadline" + "github.com/pion/transport/v3/deadline" ) var errPacketTooBig = errors.New("packet too big") @@ -38,9 +38,8 @@ type Buffer struct { data []byte head, tail int - notify chan struct{} - waiting bool - closed bool + notify chan struct{} + closed bool count int limitCount, limitSize int @@ -271,7 +270,6 @@ func (b *Buffer) Close() (err error) { return nil } - b.waiting = false b.closed = true close(b.notify) b.mutex.Unlock() diff --git a/vendor/github.com/pion/transport/v2/packetio/errors.go b/vendor/github.com/pion/transport/v3/packetio/errors.go similarity index 100% rename from vendor/github.com/pion/transport/v2/packetio/errors.go rename to vendor/github.com/pion/transport/v3/packetio/errors.go diff --git a/vendor/github.com/pion/transport/v2/packetio/hardlimit.go b/vendor/github.com/pion/transport/v3/packetio/hardlimit.go similarity index 100% rename from vendor/github.com/pion/transport/v2/packetio/hardlimit.go rename to vendor/github.com/pion/transport/v3/packetio/hardlimit.go diff --git a/vendor/github.com/pion/transport/v2/packetio/no_hardlimit.go b/vendor/github.com/pion/transport/v3/packetio/no_hardlimit.go similarity index 100% rename from vendor/github.com/pion/transport/v2/packetio/no_hardlimit.go rename to vendor/github.com/pion/transport/v3/packetio/no_hardlimit.go diff --git a/vendor/github.com/pion/transport/v2/renovate.json b/vendor/github.com/pion/transport/v3/renovate.json similarity index 100% rename from vendor/github.com/pion/transport/v2/renovate.json rename to vendor/github.com/pion/transport/v3/renovate.json diff --git a/vendor/github.com/pion/transport/v2/replaydetector/fixedbig.go b/vendor/github.com/pion/transport/v3/replaydetector/fixedbig.go similarity index 100% rename from vendor/github.com/pion/transport/v2/replaydetector/fixedbig.go rename to vendor/github.com/pion/transport/v3/replaydetector/fixedbig.go diff --git a/vendor/github.com/pion/transport/v2/replaydetector/replaydetector.go b/vendor/github.com/pion/transport/v3/replaydetector/replaydetector.go similarity index 78% rename from vendor/github.com/pion/transport/v2/replaydetector/replaydetector.go rename to vendor/github.com/pion/transport/v3/replaydetector/replaydetector.go index 4358d8f3bf..d40799568c 100644 --- a/vendor/github.com/pion/transport/v2/replaydetector/replaydetector.go +++ b/vendor/github.com/pion/transport/v3/replaydetector/replaydetector.go @@ -8,7 +8,14 @@ package replaydetector type ReplayDetector interface { // Check returns true if given sequence number is not replayed. // Call accept() to mark the packet is received properly. - Check(seq uint64) (accept func(), ok bool) + // The return value of accept() indicates whether the accepted packet is + // has the latest observed sequence number. + Check(seq uint64) (accept func() bool, ok bool) +} + +// nop is a no-op func that is returned in the case that Check() fails. +func nop() bool { + return false } type slidingWindowDetector struct { @@ -30,30 +37,33 @@ func New(windowSize uint, maxSeq uint64) ReplayDetector { } } -func (d *slidingWindowDetector) Check(seq uint64) (accept func(), ok bool) { +func (d *slidingWindowDetector) Check(seq uint64) (func() bool, bool) { if seq > d.maxSeq { // Exceeded upper limit. - return func() {}, false + return nop, false } if seq <= d.latestSeq { if d.latestSeq >= uint64(d.windowSize)+seq { - return func() {}, false + return nop, false } if d.mask.Bit(uint(d.latestSeq-seq)) != 0 { // The sequence number is duplicated. - return func() {}, false + return nop, false } } - return func() { + return func() bool { + latest := seq == 0 if seq > d.latestSeq { // Update the head of the window. d.mask.Lsh(uint(seq - d.latestSeq)) d.latestSeq = seq + latest = true } diff := (d.latestSeq - seq) % d.maxSeq d.mask.SetBit(uint(diff)) + return latest }, true } @@ -75,10 +85,10 @@ type wrappedSlidingWindowDetector struct { init bool } -func (d *wrappedSlidingWindowDetector) Check(seq uint64) (accept func(), ok bool) { +func (d *wrappedSlidingWindowDetector) Check(seq uint64) (func() bool, bool) { if seq > d.maxSeq { // Exceeded upper limit. - return func() {}, false + return nop, false } if !d.init { if seq != 0 { @@ -99,21 +109,24 @@ func (d *wrappedSlidingWindowDetector) Check(seq uint64) (accept func(), ok bool if diff >= int64(d.windowSize) { // Too old. - return func() {}, false + return nop, false } if diff >= 0 { if d.mask.Bit(uint(diff)) != 0 { // The sequence number is duplicated. - return func() {}, false + return nop, false } } - return func() { + return func() bool { + latest := false if diff < 0 { // Update the head of the window. d.mask.Lsh(uint(-diff)) d.latestSeq = seq + latest = true } d.mask.SetBit(uint(d.latestSeq - seq)) + return latest }, true } diff --git a/vendor/github.com/pion/transport/v2/stdnet/net.go b/vendor/github.com/pion/transport/v3/stdnet/net.go similarity index 99% rename from vendor/github.com/pion/transport/v2/stdnet/net.go rename to vendor/github.com/pion/transport/v3/stdnet/net.go index a2cf96438d..3d2a6e8668 100644 --- a/vendor/github.com/pion/transport/v2/stdnet/net.go +++ b/vendor/github.com/pion/transport/v3/stdnet/net.go @@ -9,7 +9,7 @@ import ( "fmt" "net" - "github.com/pion/transport/v2" + "github.com/pion/transport/v3" "github.com/wlynxg/anet" ) diff --git a/vendor/github.com/pion/transport/v2/utils/xor/xor_arm.go b/vendor/github.com/pion/transport/v3/utils/xor/xor_arm.go similarity index 100% rename from vendor/github.com/pion/transport/v2/utils/xor/xor_arm.go rename to vendor/github.com/pion/transport/v3/utils/xor/xor_arm.go diff --git a/vendor/github.com/pion/transport/v2/utils/xor/xor_arm.s b/vendor/github.com/pion/transport/v3/utils/xor/xor_arm.s similarity index 100% rename from vendor/github.com/pion/transport/v2/utils/xor/xor_arm.s rename to vendor/github.com/pion/transport/v3/utils/xor/xor_arm.s diff --git a/vendor/github.com/pion/transport/v3/utils/xor/xor_generic.go b/vendor/github.com/pion/transport/v3/utils/xor/xor_generic.go new file mode 100644 index 0000000000..690549aadc --- /dev/null +++ b/vendor/github.com/pion/transport/v3/utils/xor/xor_generic.go @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: 2013 The Go Authors. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// SPDX-FileCopyrightText: 2024 The Pion community +// SPDX-License-Identifier: MIT + +//go:build go1.20 && !arm && !gccgo + +// Package xor provides the XorBytes function. +package xor + +import ( + "crypto/subtle" +) + +// XorBytes calls [crypto/suble.XORBytes]. +// +//revive:disable-next-line +func XorBytes(dst, a, b []byte) int { + return subtle.XORBytes(dst, a, b) +} diff --git a/vendor/github.com/pion/transport/v2/utils/xor/xor_generic.go b/vendor/github.com/pion/transport/v3/utils/xor/xor_old.go similarity index 82% rename from vendor/github.com/pion/transport/v2/utils/xor/xor_generic.go rename to vendor/github.com/pion/transport/v3/utils/xor/xor_old.go index 967fed33a9..f46f4d987a 100644 --- a/vendor/github.com/pion/transport/v2/utils/xor/xor_generic.go +++ b/vendor/github.com/pion/transport/v3/utils/xor/xor_old.go @@ -3,11 +3,10 @@ // SPDX-FileCopyrightText: 2022 The Pion community // SPDX-License-Identifier: MIT -//go:build (!amd64 && !ppc64 && !ppc64le && !arm64 && !arm) || gccgo -// +build !amd64,!ppc64,!ppc64le,!arm64,!arm gccgo +//go:build (!go1.20 && !arm) || gccgo -// Package xor provides utility functions used by other Pion -// packages. Generic arch. +// Package xor provides the XorBytes function. +// This version is only used on Go up to version 1.19. package xor import ( @@ -16,8 +15,8 @@ import ( ) const ( - wordSize = int(unsafe.Sizeof(uintptr(0))) // nolint:gosec - supportsUnaligned = runtime.GOARCH == "386" || runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "s390x" // nolint:gochecknoglobals + wordSize = int(unsafe.Sizeof(uintptr(0))) // nolint:gosec + supportsUnaligned = runtime.GOARCH == "386" || runtime.GOARCH == "amd64" || runtime.GOARCH == "arm64" || runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "s390x" // nolint:gochecknoglobals ) func isAligned(a *byte) bool { diff --git a/vendor/github.com/pion/transport/v2/vnet/.gitignore b/vendor/github.com/pion/transport/v3/vnet/.gitignore similarity index 100% rename from vendor/github.com/pion/transport/v2/vnet/.gitignore rename to vendor/github.com/pion/transport/v3/vnet/.gitignore diff --git a/vendor/github.com/pion/transport/v2/vnet/README.md b/vendor/github.com/pion/transport/v3/vnet/README.md similarity index 100% rename from vendor/github.com/pion/transport/v2/vnet/README.md rename to vendor/github.com/pion/transport/v3/vnet/README.md diff --git a/vendor/github.com/pion/transport/v2/vnet/chunk.go b/vendor/github.com/pion/transport/v3/vnet/chunk.go similarity index 100% rename from vendor/github.com/pion/transport/v2/vnet/chunk.go rename to vendor/github.com/pion/transport/v3/vnet/chunk.go diff --git a/vendor/github.com/pion/transport/v2/vnet/chunk_queue.go b/vendor/github.com/pion/transport/v3/vnet/chunk_queue.go similarity index 100% rename from vendor/github.com/pion/transport/v2/vnet/chunk_queue.go rename to vendor/github.com/pion/transport/v3/vnet/chunk_queue.go diff --git a/vendor/github.com/pion/transport/v2/vnet/conn.go b/vendor/github.com/pion/transport/v3/vnet/conn.go similarity index 99% rename from vendor/github.com/pion/transport/v2/vnet/conn.go rename to vendor/github.com/pion/transport/v3/vnet/conn.go index 8f6f342698..a407f72dc5 100644 --- a/vendor/github.com/pion/transport/v2/vnet/conn.go +++ b/vendor/github.com/pion/transport/v3/vnet/conn.go @@ -12,7 +12,7 @@ import ( "sync" "time" - "github.com/pion/transport/v2" + "github.com/pion/transport/v3" ) const ( diff --git a/vendor/github.com/pion/transport/v2/vnet/conn_map.go b/vendor/github.com/pion/transport/v3/vnet/conn_map.go similarity index 100% rename from vendor/github.com/pion/transport/v2/vnet/conn_map.go rename to vendor/github.com/pion/transport/v3/vnet/conn_map.go diff --git a/vendor/github.com/pion/transport/v2/vnet/delay_filter.go b/vendor/github.com/pion/transport/v3/vnet/delay_filter.go similarity index 100% rename from vendor/github.com/pion/transport/v2/vnet/delay_filter.go rename to vendor/github.com/pion/transport/v3/vnet/delay_filter.go diff --git a/vendor/github.com/pion/transport/v2/vnet/errors.go b/vendor/github.com/pion/transport/v3/vnet/errors.go similarity index 100% rename from vendor/github.com/pion/transport/v2/vnet/errors.go rename to vendor/github.com/pion/transport/v3/vnet/errors.go diff --git a/vendor/github.com/pion/transport/v2/vnet/loss_filter.go b/vendor/github.com/pion/transport/v3/vnet/loss_filter.go similarity index 100% rename from vendor/github.com/pion/transport/v2/vnet/loss_filter.go rename to vendor/github.com/pion/transport/v3/vnet/loss_filter.go diff --git a/vendor/github.com/pion/transport/v2/vnet/nat.go b/vendor/github.com/pion/transport/v3/vnet/nat.go similarity index 100% rename from vendor/github.com/pion/transport/v2/vnet/nat.go rename to vendor/github.com/pion/transport/v3/vnet/nat.go diff --git a/vendor/github.com/pion/transport/v2/vnet/net.go b/vendor/github.com/pion/transport/v3/vnet/net.go similarity index 99% rename from vendor/github.com/pion/transport/v2/vnet/net.go rename to vendor/github.com/pion/transport/v3/vnet/net.go index 5d0938e645..08fd1f5b30 100644 --- a/vendor/github.com/pion/transport/v2/vnet/net.go +++ b/vendor/github.com/pion/transport/v3/vnet/net.go @@ -13,7 +13,7 @@ import ( "strings" "sync" - "github.com/pion/transport/v2" + "github.com/pion/transport/v3" ) const ( diff --git a/vendor/github.com/pion/transport/v2/vnet/resolver.go b/vendor/github.com/pion/transport/v3/vnet/resolver.go similarity index 100% rename from vendor/github.com/pion/transport/v2/vnet/resolver.go rename to vendor/github.com/pion/transport/v3/vnet/resolver.go diff --git a/vendor/github.com/pion/transport/v2/vnet/router.go b/vendor/github.com/pion/transport/v3/vnet/router.go similarity index 99% rename from vendor/github.com/pion/transport/v2/vnet/router.go rename to vendor/github.com/pion/transport/v3/vnet/router.go index cd4b88dc4d..cfa42116fd 100644 --- a/vendor/github.com/pion/transport/v2/vnet/router.go +++ b/vendor/github.com/pion/transport/v3/vnet/router.go @@ -14,7 +14,7 @@ import ( "time" "github.com/pion/logging" - "github.com/pion/transport/v2" + "github.com/pion/transport/v3" ) const ( diff --git a/vendor/github.com/pion/transport/v2/vnet/tbf.go b/vendor/github.com/pion/transport/v3/vnet/tbf.go similarity index 100% rename from vendor/github.com/pion/transport/v2/vnet/tbf.go rename to vendor/github.com/pion/transport/v3/vnet/tbf.go diff --git a/vendor/github.com/pion/transport/v2/vnet/udpproxy.go b/vendor/github.com/pion/transport/v3/vnet/udpproxy.go similarity index 99% rename from vendor/github.com/pion/transport/v2/vnet/udpproxy.go rename to vendor/github.com/pion/transport/v3/vnet/udpproxy.go index c5b4f99650..6de9cebb56 100644 --- a/vendor/github.com/pion/transport/v2/vnet/udpproxy.go +++ b/vendor/github.com/pion/transport/v3/vnet/udpproxy.go @@ -55,7 +55,7 @@ func NewProxy(router *Router) (*UDPProxy, error) { // Close the proxy, stop all workers. func (v *UDPProxy) Close() error { - v.workers.Range(func(key, value interface{}) bool { + v.workers.Range(func(_, value interface{}) bool { _ = value.(*aUDPProxyWorker).Close() //nolint:forcetypeassert return true }) diff --git a/vendor/github.com/pion/transport/v2/vnet/udpproxy_direct.go b/vendor/github.com/pion/transport/v3/vnet/udpproxy_direct.go similarity index 95% rename from vendor/github.com/pion/transport/v2/vnet/udpproxy_direct.go rename to vendor/github.com/pion/transport/v3/vnet/udpproxy_direct.go index bb2aedfd0d..35d815df59 100644 --- a/vendor/github.com/pion/transport/v2/vnet/udpproxy_direct.go +++ b/vendor/github.com/pion/transport/v3/vnet/udpproxy_direct.go @@ -11,7 +11,7 @@ import ( // Deliver directly send packet to vnet or real-server. // For example, we can use this API to simulate the REPLAY ATTACK. func (v *UDPProxy) Deliver(sourceAddr, destAddr net.Addr, b []byte) (nn int, err error) { - v.workers.Range(func(key, value interface{}) bool { + v.workers.Range(func(_, value interface{}) bool { if nn, err = value.(*aUDPProxyWorker).Deliver(sourceAddr, destAddr, b); err != nil { return false // Fail, abort. } else if nn == len(b) { diff --git a/vendor/github.com/pion/transport/v2/vnet/vnet.go b/vendor/github.com/pion/transport/v3/vnet/vnet.go similarity index 100% rename from vendor/github.com/pion/transport/v2/vnet/vnet.go rename to vendor/github.com/pion/transport/v3/vnet/vnet.go diff --git a/vendor/github.com/pion/turn/v2/.golangci.yml b/vendor/github.com/pion/turn/v2/.golangci.yml deleted file mode 100644 index 4e3eddf429..0000000000 --- a/vendor/github.com/pion/turn/v2/.golangci.yml +++ /dev/null @@ -1,137 +0,0 @@ -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -linters-settings: - govet: - check-shadowing: true - misspell: - locale: US - exhaustive: - default-signifies-exhaustive: true - gomodguard: - blocked: - modules: - - github.com/pkg/errors: - recommendations: - - errors - forbidigo: - forbid: - - ^fmt.Print(f|ln)?$ - - ^log.(Panic|Fatal|Print)(f|ln)?$ - - ^os.Exit$ - - ^panic$ - - ^print(ln)?$ - -linters: - enable: - - asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers - - bidichk # Checks for dangerous unicode character sequences - - bodyclose # checks whether HTTP response body is closed successfully - - contextcheck # check the function whether use a non-inherited context - - decorder # check declaration order and count of types, constants, variables and functions - - depguard # Go linter that checks if package imports are in a list of acceptable packages - - dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) - - dupl # Tool for code clone detection - - durationcheck # check for two durations multiplied together - - errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases - - errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and optionally reports occations, where the check for the returned error can be omitted. - - errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. - - errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13. - - exhaustive # check exhaustiveness of enum switch statements - - exportloopref # checks for pointers to enclosing loop variables - - forbidigo # Forbids identifiers - - forcetypeassert # finds forced type assertions - - gci # Gci control golang package import order and make it always deterministic. - - gochecknoglobals # Checks that no globals are present in Go code - - gochecknoinits # Checks that no init functions are present in Go code - - gocognit # Computes and checks the cognitive complexity of functions - - goconst # Finds repeated strings that could be replaced by a constant - - gocritic # The most opinionated Go source code linter - - godox # Tool for detection of FIXME, TODO and other comment keywords - - goerr113 # Golang linter to check the errors handling expressions - - gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification - - gofumpt # Gofumpt checks whether code was gofumpt-ed. - - goheader # Checks is file header matches to pattern - - goimports # Goimports does everything that gofmt does. Additionally it checks unused imports - - gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. - - gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. - - goprintffuncname # Checks that printf-like functions are named with `f` at the end - - gosec # Inspects source code for security problems - - gosimple # Linter for Go source code that specializes in simplifying a code - - govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string - - grouper # An analyzer to analyze expression groups. - - importas # Enforces consistent import aliases - - ineffassign # Detects when assignments to existing variables are not used - - misspell # Finds commonly misspelled English words in comments - - nakedret # Finds naked returns in functions greater than a specified function length - - nilerr # Finds the code that returns nil even if it checks that the error is not nil. - - nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. - - noctx # noctx finds sending http request without context.Context - - predeclared # find code that shadows one of Go's predeclared identifiers - - revive # golint replacement, finds style mistakes - - staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks - - stylecheck # Stylecheck is a replacement for golint - - tagliatelle # Checks the struct tags. - - tenv # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17 - - tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes - - typecheck # Like the front-end of a Go compiler, parses and type-checks Go code - - unconvert # Remove unnecessary type conversions - - unparam # Reports unused function parameters - - unused # Checks Go code for unused constants, variables, functions and types - - wastedassign # wastedassign finds wasted assignment statements - - whitespace # Tool for detection of leading and trailing whitespace - disable: - - containedctx # containedctx is a linter that detects struct contained context.Context field - - cyclop # checks function and package cyclomatic complexity - - exhaustivestruct # Checks if all struct's fields are initialized - - funlen # Tool for detection of long functions - - gocyclo # Computes and checks the cyclomatic complexity of functions - - godot # Check if comments end in a period - - gomnd # An analyzer to detect magic numbers. - - ifshort # Checks that your code uses short syntax for if-statements whenever possible - - ireturn # Accept Interfaces, Return Concrete Types - - lll # Reports long lines - - maintidx # maintidx measures the maintainability index of each function. - - makezero # Finds slice declarations with non-zero initial length - - maligned # Tool to detect Go structs that would take less memory if their fields were sorted - - nestif # Reports deeply nested if statements - - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity - - nolintlint # Reports ill-formed or insufficient nolint directives - - paralleltest # paralleltest detects missing usage of t.Parallel() method in your Go test - - prealloc # Finds slice declarations that could potentially be preallocated - - promlinter # Check Prometheus metrics naming via promlint - - rowserrcheck # checks whether Err of rows is checked successfully - - sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed. - - testpackage # linter that makes you use a separate _test package - - thelper # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers - - varnamelen # checks that the length of a variable's name matches its scope - - wrapcheck # Checks that errors returned from external packages are wrapped - - wsl # Whitespace Linter - Forces you to use empty lines! - -issues: - exclude-use-default: false - exclude-rules: - # Allow complex tests, better to be self contained - - path: _test\.go - linters: - - gocognit - - forbidigo - - # Allow complex main function in examples - - path: examples - text: "of func `main` is high" - linters: - - gocognit - - # Allow forbidden identifiers in examples - - path: examples - linters: - - forbidigo - - # Allow forbidden identifiers in CLI commands - - path: cmd - linters: - - forbidigo - -run: - skip-dirs-use-default: false diff --git a/vendor/github.com/pion/turn/v2/AUTHORS.txt b/vendor/github.com/pion/turn/v2/AUTHORS.txt deleted file mode 100644 index ea984983ef..0000000000 --- a/vendor/github.com/pion/turn/v2/AUTHORS.txt +++ /dev/null @@ -1,48 +0,0 @@ -# Thank you to everyone that made Pion possible. If you are interested in contributing -# we would love to have you https://github.com/pion/webrtc/wiki/Contributing -# -# This file is auto generated, using git to list all individuals contributors. -# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting -Aaron France -Aleksandr Razumov -anastasia -andrefsp -Andy Yan -Antonio Sorrentino -Artem Yarovenko -Atsushi Watanabe -backkem -boks1971 -Caleb Phillips -cnderrauber -David Colburn -Gabor Retvari -Harold Thetiot -Herman Banken -Hugo Arregui -Igor German -Ingmar Wittkau -Jannis Mattheis -John Bradley -jose nazario -Juliusz Chroboczek -lllf -Lukas Rezek -Marouane <6729798+nindolabs@users.noreply.github.com> -Mészáros Mihály -nindolabs <6729798+nindolabs@users.noreply.github.com> -Onwuka Gideon -Robert Eperjesi -Sean DuBois -Sean DuBois -Sean DuBois -Sean DuBois -songjiayang -Steffen Vogel -ted -Tom Clift -Yusuke Nakamura -Yutaka Takeda - -# List of contributors not appearing in Git history - diff --git a/vendor/github.com/pion/turn/v2/.gitignore b/vendor/github.com/pion/turn/v4/.gitignore similarity index 100% rename from vendor/github.com/pion/turn/v2/.gitignore rename to vendor/github.com/pion/turn/v4/.gitignore diff --git a/vendor/github.com/pion/ice/v2/.golangci.yml b/vendor/github.com/pion/turn/v4/.golangci.yml similarity index 95% rename from vendor/github.com/pion/ice/v2/.golangci.yml rename to vendor/github.com/pion/turn/v4/.golangci.yml index 4e3eddf429..e06de4d3c0 100644 --- a/vendor/github.com/pion/ice/v2/.golangci.yml +++ b/vendor/github.com/pion/turn/v4/.golangci.yml @@ -3,7 +3,8 @@ linters-settings: govet: - check-shadowing: true + enable: + - shadow misspell: locale: US exhaustive: @@ -29,7 +30,6 @@ linters: - bodyclose # checks whether HTTP response body is closed successfully - contextcheck # check the function whether use a non-inherited context - decorder # check declaration order and count of types, constants, variables and functions - - depguard # Go linter that checks if package imports are in a list of acceptable packages - dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) - dupl # Tool for code clone detection - durationcheck # check for two durations multiplied together @@ -63,7 +63,6 @@ linters: - importas # Enforces consistent import aliases - ineffassign # Detects when assignments to existing variables are not used - misspell # Finds commonly misspelled English words in comments - - nakedret # Finds naked returns in functions greater than a specified function length - nilerr # Finds the code that returns nil even if it checks that the error is not nil. - nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. - noctx # noctx finds sending http request without context.Context @@ -81,6 +80,7 @@ linters: - wastedassign # wastedassign finds wasted assignment statements - whitespace # Tool for detection of leading and trailing whitespace disable: + - depguard # Go linter that checks if package imports are in a list of acceptable packages - containedctx # containedctx is a linter that detects struct contained context.Context field - cyclop # checks function and package cyclomatic complexity - exhaustivestruct # Checks if all struct's fields are initialized @@ -94,6 +94,7 @@ linters: - maintidx # maintidx measures the maintainability index of each function. - makezero # Finds slice declarations with non-zero initial length - maligned # Tool to detect Go structs that would take less memory if their fields were sorted + - nakedret # Finds naked returns in functions greater than a specified function length - nestif # Reports deeply nested if statements - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity - nolintlint # Reports ill-formed or insufficient nolint directives @@ -110,28 +111,15 @@ linters: issues: exclude-use-default: false + exclude-dirs-use-default: false exclude-rules: - # Allow complex tests, better to be self contained - - path: _test\.go + # Allow complex tests and examples, better to be self contained + - path: (examples|main\.go|_test\.go) linters: - - gocognit - forbidigo - - # Allow complex main function in examples - - path: examples - text: "of func `main` is high" - linters: - gocognit - - # Allow forbidden identifiers in examples - - path: examples - linters: - - forbidigo # Allow forbidden identifiers in CLI commands - path: cmd linters: - forbidigo - -run: - skip-dirs-use-default: false diff --git a/vendor/github.com/pion/turn/v2/.goreleaser.yml b/vendor/github.com/pion/turn/v4/.goreleaser.yml similarity index 100% rename from vendor/github.com/pion/turn/v2/.goreleaser.yml rename to vendor/github.com/pion/turn/v4/.goreleaser.yml diff --git a/vendor/github.com/pion/turn/v2/LICENSE b/vendor/github.com/pion/turn/v4/LICENSE similarity index 100% rename from vendor/github.com/pion/turn/v2/LICENSE rename to vendor/github.com/pion/turn/v4/LICENSE diff --git a/vendor/github.com/pion/turn/v2/README.md b/vendor/github.com/pion/turn/v4/README.md similarity index 95% rename from vendor/github.com/pion/turn/v2/README.md rename to vendor/github.com/pion/turn/v4/README.md index 5adcfe7df1..a571c0ba98 100644 --- a/vendor/github.com/pion/turn/v2/README.md +++ b/vendor/github.com/pion/turn/v4/README.md @@ -11,9 +11,9 @@
GitHub Workflow Status - Go Reference + Go Reference Coverage Status - Go Report Card + Go Report Card License: MIT


@@ -87,7 +87,7 @@ We are always looking to support **your projects**. Please reach out if you have If you need commercial support or don't want to use public methods you can contact us at [team@pion.ly](mailto:team@pion.ly) ### Contributing -Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible: [AUTHORS.txt](./AUTHORS.txt) +Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible ### License MIT License - see [LICENSE](LICENSE) for full text diff --git a/vendor/github.com/pion/turn/v2/client.go b/vendor/github.com/pion/turn/v4/client.go similarity index 98% rename from vendor/github.com/pion/turn/v2/client.go rename to vendor/github.com/pion/turn/v4/client.go index 350715c63f..6e38ae1094 100644 --- a/vendor/github.com/pion/turn/v2/client.go +++ b/vendor/github.com/pion/turn/v4/client.go @@ -12,11 +12,11 @@ import ( "time" "github.com/pion/logging" - "github.com/pion/stun" - "github.com/pion/transport/v2" - "github.com/pion/transport/v2/stdnet" - "github.com/pion/turn/v2/internal/client" - "github.com/pion/turn/v2/internal/proto" + "github.com/pion/stun/v3" + "github.com/pion/transport/v3" + "github.com/pion/transport/v3/stdnet" + "github.com/pion/turn/v4/internal/client" + "github.com/pion/turn/v4/internal/proto" ) const ( diff --git a/vendor/github.com/pion/turn/v2/codecov.yml b/vendor/github.com/pion/turn/v4/codecov.yml similarity index 100% rename from vendor/github.com/pion/turn/v2/codecov.yml rename to vendor/github.com/pion/turn/v4/codecov.yml diff --git a/vendor/github.com/pion/turn/v2/errors.go b/vendor/github.com/pion/turn/v4/errors.go similarity index 96% rename from vendor/github.com/pion/turn/v2/errors.go rename to vendor/github.com/pion/turn/v4/errors.go index 50065e27b7..3ebd26ae8a 100644 --- a/vendor/github.com/pion/turn/v2/errors.go +++ b/vendor/github.com/pion/turn/v4/errors.go @@ -28,4 +28,5 @@ var ( errNonSTUNMessage = errors.New("non-STUN message from STUN server") errFailedToDecodeSTUN = errors.New("failed to decode STUN message") errUnexpectedSTUNRequestMessage = errors.New("unexpected STUN request message") + errRelayAddressGeneratorNil = errors.New("RelayAddressGenerator is nil") ) diff --git a/vendor/github.com/pion/turn/v2/internal/allocation/allocation.go b/vendor/github.com/pion/turn/v4/internal/allocation/allocation.go similarity index 98% rename from vendor/github.com/pion/turn/v2/internal/allocation/allocation.go rename to vendor/github.com/pion/turn/v4/internal/allocation/allocation.go index 9bfd910534..5b5ff369be 100644 --- a/vendor/github.com/pion/turn/v2/internal/allocation/allocation.go +++ b/vendor/github.com/pion/turn/v4/internal/allocation/allocation.go @@ -11,9 +11,9 @@ import ( "time" "github.com/pion/logging" - "github.com/pion/stun" - "github.com/pion/turn/v2/internal/ipnet" - "github.com/pion/turn/v2/internal/proto" + "github.com/pion/stun/v3" + "github.com/pion/turn/v4/internal/ipnet" + "github.com/pion/turn/v4/internal/proto" ) type allocationResponse struct { diff --git a/vendor/github.com/pion/turn/v2/internal/allocation/allocation_manager.go b/vendor/github.com/pion/turn/v4/internal/allocation/allocation_manager.go similarity index 100% rename from vendor/github.com/pion/turn/v2/internal/allocation/allocation_manager.go rename to vendor/github.com/pion/turn/v4/internal/allocation/allocation_manager.go diff --git a/vendor/github.com/pion/turn/v2/internal/allocation/channel_bind.go b/vendor/github.com/pion/turn/v4/internal/allocation/channel_bind.go similarity index 96% rename from vendor/github.com/pion/turn/v2/internal/allocation/channel_bind.go rename to vendor/github.com/pion/turn/v4/internal/allocation/channel_bind.go index d38de3514f..19b1843175 100644 --- a/vendor/github.com/pion/turn/v2/internal/allocation/channel_bind.go +++ b/vendor/github.com/pion/turn/v4/internal/allocation/channel_bind.go @@ -8,7 +8,7 @@ import ( "time" "github.com/pion/logging" - "github.com/pion/turn/v2/internal/proto" + "github.com/pion/turn/v4/internal/proto" ) // ChannelBind represents a TURN Channel diff --git a/vendor/github.com/pion/turn/v2/internal/allocation/errors.go b/vendor/github.com/pion/turn/v4/internal/allocation/errors.go similarity index 100% rename from vendor/github.com/pion/turn/v2/internal/allocation/errors.go rename to vendor/github.com/pion/turn/v4/internal/allocation/errors.go diff --git a/vendor/github.com/pion/turn/v2/internal/allocation/five_tuple.go b/vendor/github.com/pion/turn/v4/internal/allocation/five_tuple.go similarity index 100% rename from vendor/github.com/pion/turn/v2/internal/allocation/five_tuple.go rename to vendor/github.com/pion/turn/v4/internal/allocation/five_tuple.go diff --git a/vendor/github.com/pion/turn/v2/internal/allocation/permission.go b/vendor/github.com/pion/turn/v4/internal/allocation/permission.go similarity index 100% rename from vendor/github.com/pion/turn/v2/internal/allocation/permission.go rename to vendor/github.com/pion/turn/v4/internal/allocation/permission.go diff --git a/vendor/github.com/pion/turn/v2/internal/client/allocation.go b/vendor/github.com/pion/turn/v4/internal/client/allocation.go similarity index 97% rename from vendor/github.com/pion/turn/v2/internal/client/allocation.go rename to vendor/github.com/pion/turn/v4/internal/client/allocation.go index f61452b71c..a7f7463605 100644 --- a/vendor/github.com/pion/turn/v2/internal/client/allocation.go +++ b/vendor/github.com/pion/turn/v4/internal/client/allocation.go @@ -11,9 +11,9 @@ import ( "time" "github.com/pion/logging" - "github.com/pion/stun" - "github.com/pion/transport/v2" - "github.com/pion/turn/v2/internal/proto" + "github.com/pion/stun/v3" + "github.com/pion/transport/v3" + "github.com/pion/turn/v4/internal/proto" ) // AllocationConfig is a set of configuration params use by NewUDPConn and NewTCPAllocation diff --git a/vendor/github.com/pion/turn/v2/internal/client/binding.go b/vendor/github.com/pion/turn/v4/internal/client/binding.go similarity index 100% rename from vendor/github.com/pion/turn/v2/internal/client/binding.go rename to vendor/github.com/pion/turn/v4/internal/client/binding.go diff --git a/vendor/github.com/pion/turn/v2/internal/client/client.go b/vendor/github.com/pion/turn/v4/internal/client/client.go similarity index 94% rename from vendor/github.com/pion/turn/v2/internal/client/client.go rename to vendor/github.com/pion/turn/v4/internal/client/client.go index 7c22858f1a..10b49a284f 100644 --- a/vendor/github.com/pion/turn/v2/internal/client/client.go +++ b/vendor/github.com/pion/turn/v4/internal/client/client.go @@ -7,7 +7,7 @@ package client import ( "net" - "github.com/pion/stun" + "github.com/pion/stun/v3" ) // Client is an interface for the public turn.Client in order to break cyclic dependencies diff --git a/vendor/github.com/pion/turn/v2/internal/client/errors.go b/vendor/github.com/pion/turn/v4/internal/client/errors.go similarity index 100% rename from vendor/github.com/pion/turn/v2/internal/client/errors.go rename to vendor/github.com/pion/turn/v4/internal/client/errors.go diff --git a/vendor/github.com/pion/turn/v2/internal/client/periodic_timer.go b/vendor/github.com/pion/turn/v4/internal/client/periodic_timer.go similarity index 100% rename from vendor/github.com/pion/turn/v2/internal/client/periodic_timer.go rename to vendor/github.com/pion/turn/v4/internal/client/periodic_timer.go diff --git a/vendor/github.com/pion/turn/v2/internal/client/permission.go b/vendor/github.com/pion/turn/v4/internal/client/permission.go similarity index 97% rename from vendor/github.com/pion/turn/v2/internal/client/permission.go rename to vendor/github.com/pion/turn/v4/internal/client/permission.go index f5df0ccf88..0436e4ea63 100644 --- a/vendor/github.com/pion/turn/v2/internal/client/permission.go +++ b/vendor/github.com/pion/turn/v4/internal/client/permission.go @@ -8,7 +8,7 @@ import ( "sync" "sync/atomic" - "github.com/pion/turn/v2/internal/ipnet" + "github.com/pion/turn/v4/internal/ipnet" ) type permState int32 diff --git a/vendor/github.com/pion/turn/v2/internal/client/tcp_alloc.go b/vendor/github.com/pion/turn/v4/internal/client/tcp_alloc.go similarity index 97% rename from vendor/github.com/pion/turn/v2/internal/client/tcp_alloc.go rename to vendor/github.com/pion/turn/v4/internal/client/tcp_alloc.go index 3d6838b317..82948387cc 100644 --- a/vendor/github.com/pion/turn/v2/internal/client/tcp_alloc.go +++ b/vendor/github.com/pion/turn/v4/internal/client/tcp_alloc.go @@ -11,9 +11,9 @@ import ( "net" "time" - "github.com/pion/stun" - "github.com/pion/transport/v2" - "github.com/pion/turn/v2/internal/proto" + "github.com/pion/stun/v3" + "github.com/pion/transport/v3" + "github.com/pion/turn/v4/internal/proto" ) var ( @@ -151,6 +151,11 @@ func (a *TCPAllocation) DialTCP(network string, lAddr, rAddr *net.TCPAddr) (*TCP IP: addr.IP, Port: addr.Port, } + } else if addr, ok := a.serverAddr.(*net.UDPAddr); ok { + rAddrServer = &net.TCPAddr{ + IP: addr.IP, + Port: addr.Port, + } } else { return nil, errInvalidTURNAddress } diff --git a/vendor/github.com/pion/turn/v2/internal/client/tcp_conn.go b/vendor/github.com/pion/turn/v4/internal/client/tcp_conn.go similarity index 94% rename from vendor/github.com/pion/turn/v2/internal/client/tcp_conn.go rename to vendor/github.com/pion/turn/v4/internal/client/tcp_conn.go index 06d50eb26a..990b6d4245 100644 --- a/vendor/github.com/pion/turn/v2/internal/client/tcp_conn.go +++ b/vendor/github.com/pion/turn/v4/internal/client/tcp_conn.go @@ -7,8 +7,8 @@ import ( "errors" "net" - "github.com/pion/transport/v2" - "github.com/pion/turn/v2/internal/proto" + "github.com/pion/transport/v3" + "github.com/pion/turn/v4/internal/proto" ) var ( diff --git a/vendor/github.com/pion/turn/v2/internal/client/transaction.go b/vendor/github.com/pion/turn/v4/internal/client/transaction.go similarity index 99% rename from vendor/github.com/pion/turn/v2/internal/client/transaction.go rename to vendor/github.com/pion/turn/v4/internal/client/transaction.go index e447553245..b1c9105e6a 100644 --- a/vendor/github.com/pion/turn/v2/internal/client/transaction.go +++ b/vendor/github.com/pion/turn/v4/internal/client/transaction.go @@ -8,7 +8,7 @@ import ( "sync" "time" - "github.com/pion/stun" + "github.com/pion/stun/v3" ) const ( diff --git a/vendor/github.com/pion/turn/v2/internal/client/trylock.go b/vendor/github.com/pion/turn/v4/internal/client/trylock.go similarity index 100% rename from vendor/github.com/pion/turn/v2/internal/client/trylock.go rename to vendor/github.com/pion/turn/v4/internal/client/trylock.go diff --git a/vendor/github.com/pion/turn/v2/internal/client/udp_conn.go b/vendor/github.com/pion/turn/v4/internal/client/udp_conn.go similarity index 99% rename from vendor/github.com/pion/turn/v2/internal/client/udp_conn.go rename to vendor/github.com/pion/turn/v4/internal/client/udp_conn.go index f73bf5b17a..7bb187659a 100644 --- a/vendor/github.com/pion/turn/v2/internal/client/udp_conn.go +++ b/vendor/github.com/pion/turn/v4/internal/client/udp_conn.go @@ -12,8 +12,8 @@ import ( "net" "time" - "github.com/pion/stun" - "github.com/pion/turn/v2/internal/proto" + "github.com/pion/stun/v3" + "github.com/pion/turn/v4/internal/proto" ) const ( diff --git a/vendor/github.com/pion/turn/v2/internal/ipnet/util.go b/vendor/github.com/pion/turn/v4/internal/ipnet/util.go similarity index 100% rename from vendor/github.com/pion/turn/v2/internal/ipnet/util.go rename to vendor/github.com/pion/turn/v4/internal/ipnet/util.go diff --git a/vendor/github.com/pion/turn/v2/internal/proto/addr.go b/vendor/github.com/pion/turn/v4/internal/proto/addr.go similarity index 100% rename from vendor/github.com/pion/turn/v2/internal/proto/addr.go rename to vendor/github.com/pion/turn/v4/internal/proto/addr.go diff --git a/vendor/github.com/pion/turn/v2/internal/proto/chandata.go b/vendor/github.com/pion/turn/v4/internal/proto/chandata.go similarity index 100% rename from vendor/github.com/pion/turn/v2/internal/proto/chandata.go rename to vendor/github.com/pion/turn/v4/internal/proto/chandata.go diff --git a/vendor/github.com/pion/turn/v2/internal/proto/chann.go b/vendor/github.com/pion/turn/v4/internal/proto/chann.go similarity index 98% rename from vendor/github.com/pion/turn/v2/internal/proto/chann.go rename to vendor/github.com/pion/turn/v4/internal/proto/chann.go index f85c6a170f..3aeb59f38d 100644 --- a/vendor/github.com/pion/turn/v2/internal/proto/chann.go +++ b/vendor/github.com/pion/turn/v4/internal/proto/chann.go @@ -8,7 +8,7 @@ import ( "errors" "strconv" - "github.com/pion/stun" + "github.com/pion/stun/v3" ) // ChannelNumber represents CHANNEL-NUMBER attribute. diff --git a/vendor/github.com/pion/turn/v2/internal/proto/connection_id.go b/vendor/github.com/pion/turn/v4/internal/proto/connection_id.go similarity index 97% rename from vendor/github.com/pion/turn/v2/internal/proto/connection_id.go rename to vendor/github.com/pion/turn/v4/internal/proto/connection_id.go index 8827da6b3a..568deff15a 100644 --- a/vendor/github.com/pion/turn/v2/internal/proto/connection_id.go +++ b/vendor/github.com/pion/turn/v4/internal/proto/connection_id.go @@ -6,7 +6,7 @@ package proto import ( "encoding/binary" - "github.com/pion/stun" + "github.com/pion/stun/v3" ) // ConnectionID represents CONNECTION-ID attribute. diff --git a/vendor/github.com/pion/turn/v2/internal/proto/data.go b/vendor/github.com/pion/turn/v4/internal/proto/data.go similarity index 96% rename from vendor/github.com/pion/turn/v2/internal/proto/data.go rename to vendor/github.com/pion/turn/v4/internal/proto/data.go index d3cf31300c..dcba23b44a 100644 --- a/vendor/github.com/pion/turn/v2/internal/proto/data.go +++ b/vendor/github.com/pion/turn/v4/internal/proto/data.go @@ -3,7 +3,7 @@ package proto -import "github.com/pion/stun" +import "github.com/pion/stun/v3" // Data represents DATA attribute. // diff --git a/vendor/github.com/pion/turn/v2/internal/proto/dontfrag.go b/vendor/github.com/pion/turn/v4/internal/proto/dontfrag.go similarity index 97% rename from vendor/github.com/pion/turn/v2/internal/proto/dontfrag.go rename to vendor/github.com/pion/turn/v4/internal/proto/dontfrag.go index 317938cb92..e4be0af676 100644 --- a/vendor/github.com/pion/turn/v2/internal/proto/dontfrag.go +++ b/vendor/github.com/pion/turn/v4/internal/proto/dontfrag.go @@ -4,7 +4,7 @@ package proto import ( - "github.com/pion/stun" + "github.com/pion/stun/v3" ) // DontFragmentAttr is a deprecated alias for DontFragment diff --git a/vendor/github.com/pion/turn/v2/internal/proto/evenport.go b/vendor/github.com/pion/turn/v4/internal/proto/evenport.go similarity index 97% rename from vendor/github.com/pion/turn/v2/internal/proto/evenport.go rename to vendor/github.com/pion/turn/v4/internal/proto/evenport.go index c41df3296f..31468c757f 100644 --- a/vendor/github.com/pion/turn/v2/internal/proto/evenport.go +++ b/vendor/github.com/pion/turn/v4/internal/proto/evenport.go @@ -3,7 +3,7 @@ package proto -import "github.com/pion/stun" +import "github.com/pion/stun/v3" // EvenPort represents EVEN-PORT attribute. // diff --git a/vendor/github.com/pion/turn/v2/internal/proto/lifetime.go b/vendor/github.com/pion/turn/v4/internal/proto/lifetime.go similarity index 98% rename from vendor/github.com/pion/turn/v2/internal/proto/lifetime.go rename to vendor/github.com/pion/turn/v4/internal/proto/lifetime.go index 4405c77aa7..6f55c7a978 100644 --- a/vendor/github.com/pion/turn/v2/internal/proto/lifetime.go +++ b/vendor/github.com/pion/turn/v4/internal/proto/lifetime.go @@ -7,7 +7,7 @@ import ( "encoding/binary" "time" - "github.com/pion/stun" + "github.com/pion/stun/v3" ) // DefaultLifetime in RFC 5766 is 10 minutes. diff --git a/vendor/github.com/pion/turn/v2/internal/proto/peeraddr.go b/vendor/github.com/pion/turn/v4/internal/proto/peeraddr.go similarity index 97% rename from vendor/github.com/pion/turn/v2/internal/proto/peeraddr.go rename to vendor/github.com/pion/turn/v4/internal/proto/peeraddr.go index a562d5a11a..f4d9de7b6f 100644 --- a/vendor/github.com/pion/turn/v2/internal/proto/peeraddr.go +++ b/vendor/github.com/pion/turn/v4/internal/proto/peeraddr.go @@ -6,7 +6,7 @@ package proto import ( "net" - "github.com/pion/stun" + "github.com/pion/stun/v3" ) // PeerAddress implements XOR-PEER-ADDRESS attribute. diff --git a/vendor/github.com/pion/turn/v2/internal/proto/proto.go b/vendor/github.com/pion/turn/v4/internal/proto/proto.go similarity index 97% rename from vendor/github.com/pion/turn/v2/internal/proto/proto.go rename to vendor/github.com/pion/turn/v4/internal/proto/proto.go index e5842687fc..170cf7f188 100644 --- a/vendor/github.com/pion/turn/v2/internal/proto/proto.go +++ b/vendor/github.com/pion/turn/v4/internal/proto/proto.go @@ -5,7 +5,7 @@ package proto import ( - "github.com/pion/stun" + "github.com/pion/stun/v3" ) // Default ports for TURN from RFC 5766 Section 4. diff --git a/vendor/github.com/pion/turn/v2/internal/proto/relayedaddr.go b/vendor/github.com/pion/turn/v4/internal/proto/relayedaddr.go similarity index 97% rename from vendor/github.com/pion/turn/v2/internal/proto/relayedaddr.go rename to vendor/github.com/pion/turn/v4/internal/proto/relayedaddr.go index d4dcc7535f..c5fb2686cf 100644 --- a/vendor/github.com/pion/turn/v2/internal/proto/relayedaddr.go +++ b/vendor/github.com/pion/turn/v4/internal/proto/relayedaddr.go @@ -6,7 +6,7 @@ package proto import ( "net" - "github.com/pion/stun" + "github.com/pion/stun/v3" ) // RelayedAddress implements XOR-RELAYED-ADDRESS attribute. diff --git a/vendor/github.com/pion/turn/v2/internal/proto/reqfamily.go b/vendor/github.com/pion/turn/v4/internal/proto/reqfamily.go similarity index 98% rename from vendor/github.com/pion/turn/v2/internal/proto/reqfamily.go rename to vendor/github.com/pion/turn/v4/internal/proto/reqfamily.go index 8c18f9d521..01016a9870 100644 --- a/vendor/github.com/pion/turn/v2/internal/proto/reqfamily.go +++ b/vendor/github.com/pion/turn/v4/internal/proto/reqfamily.go @@ -6,7 +6,7 @@ package proto import ( "errors" - "github.com/pion/stun" + "github.com/pion/stun/v3" ) // RequestedAddressFamily represents the REQUESTED-ADDRESS-FAMILY Attribute as diff --git a/vendor/github.com/pion/turn/v2/internal/proto/reqtrans.go b/vendor/github.com/pion/turn/v4/internal/proto/reqtrans.go similarity index 98% rename from vendor/github.com/pion/turn/v2/internal/proto/reqtrans.go rename to vendor/github.com/pion/turn/v4/internal/proto/reqtrans.go index 5dd446d3a2..111dcd69b9 100644 --- a/vendor/github.com/pion/turn/v2/internal/proto/reqtrans.go +++ b/vendor/github.com/pion/turn/v4/internal/proto/reqtrans.go @@ -6,7 +6,7 @@ package proto import ( "strconv" - "github.com/pion/stun" + "github.com/pion/stun/v3" ) // Protocol is IANA assigned protocol number. diff --git a/vendor/github.com/pion/turn/v2/internal/proto/rsrvtoken.go b/vendor/github.com/pion/turn/v4/internal/proto/rsrvtoken.go similarity index 97% rename from vendor/github.com/pion/turn/v2/internal/proto/rsrvtoken.go rename to vendor/github.com/pion/turn/v4/internal/proto/rsrvtoken.go index ec72fc7cfe..9c816485d3 100644 --- a/vendor/github.com/pion/turn/v2/internal/proto/rsrvtoken.go +++ b/vendor/github.com/pion/turn/v4/internal/proto/rsrvtoken.go @@ -3,7 +3,7 @@ package proto -import "github.com/pion/stun" +import "github.com/pion/stun/v3" // ReservationToken represents RESERVATION-TOKEN attribute. // diff --git a/vendor/github.com/pion/turn/v2/internal/server/errors.go b/vendor/github.com/pion/turn/v4/internal/server/errors.go similarity index 100% rename from vendor/github.com/pion/turn/v2/internal/server/errors.go rename to vendor/github.com/pion/turn/v4/internal/server/errors.go diff --git a/vendor/github.com/pion/turn/v2/internal/server/nonce.go b/vendor/github.com/pion/turn/v4/internal/server/nonce.go similarity index 100% rename from vendor/github.com/pion/turn/v2/internal/server/nonce.go rename to vendor/github.com/pion/turn/v4/internal/server/nonce.go diff --git a/vendor/github.com/pion/turn/v2/internal/server/server.go b/vendor/github.com/pion/turn/v4/internal/server/server.go similarity index 96% rename from vendor/github.com/pion/turn/v2/internal/server/server.go rename to vendor/github.com/pion/turn/v4/internal/server/server.go index 097cb9f057..253492e927 100644 --- a/vendor/github.com/pion/turn/v2/internal/server/server.go +++ b/vendor/github.com/pion/turn/v4/internal/server/server.go @@ -10,9 +10,9 @@ import ( "time" "github.com/pion/logging" - "github.com/pion/stun" - "github.com/pion/turn/v2/internal/allocation" - "github.com/pion/turn/v2/internal/proto" + "github.com/pion/stun/v3" + "github.com/pion/turn/v4/internal/allocation" + "github.com/pion/turn/v4/internal/proto" ) // Request contains all the state needed to process a single incoming datagram diff --git a/vendor/github.com/pion/turn/v2/internal/server/stun.go b/vendor/github.com/pion/turn/v4/internal/server/stun.go similarity index 88% rename from vendor/github.com/pion/turn/v2/internal/server/stun.go rename to vendor/github.com/pion/turn/v4/internal/server/stun.go index b8596d1295..393bb99d89 100644 --- a/vendor/github.com/pion/turn/v2/internal/server/stun.go +++ b/vendor/github.com/pion/turn/v4/internal/server/stun.go @@ -4,8 +4,8 @@ package server import ( - "github.com/pion/stun" - "github.com/pion/turn/v2/internal/ipnet" + "github.com/pion/stun/v3" + "github.com/pion/turn/v4/internal/ipnet" ) func handleBindingRequest(r Request, m *stun.Message) error { diff --git a/vendor/github.com/pion/turn/v2/internal/server/turn.go b/vendor/github.com/pion/turn/v4/internal/server/turn.go similarity index 97% rename from vendor/github.com/pion/turn/v2/internal/server/turn.go rename to vendor/github.com/pion/turn/v4/internal/server/turn.go index cd84834c9c..46e45ecbee 100644 --- a/vendor/github.com/pion/turn/v2/internal/server/turn.go +++ b/vendor/github.com/pion/turn/v4/internal/server/turn.go @@ -7,12 +7,15 @@ import ( "fmt" "net" - "github.com/pion/stun" - "github.com/pion/turn/v2/internal/allocation" - "github.com/pion/turn/v2/internal/ipnet" - "github.com/pion/turn/v2/internal/proto" + "github.com/pion/randutil" + "github.com/pion/stun/v3" + "github.com/pion/turn/v4/internal/allocation" + "github.com/pion/turn/v4/internal/ipnet" + "github.com/pion/turn/v4/internal/proto" ) +const runesAlpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + // See: https://tools.ietf.org/html/rfc5766#section-6.2 func handleAllocateRequest(r Request, m *stun.Message) error { r.Log.Debugf("Received AllocateRequest from %s", r.SrcAddr) @@ -106,7 +109,10 @@ func handleAllocateRequest(r Request, m *stun.Message) error { return buildAndSendErr(r.Conn, r.SrcAddr, err, insufficientCapacityMsg...) } requestedPort = randomPort - reservationToken = randSeq(8) + reservationToken, err = randutil.GenerateCryptoRandomString(8, runesAlpha) + if err != nil { + return err + } } // 7. At any point, the server MAY choose to reject the request with a diff --git a/vendor/github.com/pion/turn/v2/internal/server/util.go b/vendor/github.com/pion/turn/v4/internal/server/util.go similarity index 91% rename from vendor/github.com/pion/turn/v2/internal/server/util.go rename to vendor/github.com/pion/turn/v4/internal/server/util.go index caa46e3026..7c01d3297b 100644 --- a/vendor/github.com/pion/turn/v2/internal/server/util.go +++ b/vendor/github.com/pion/turn/v4/internal/server/util.go @@ -6,27 +6,17 @@ package server import ( "errors" "fmt" - "math/rand" "net" "time" - "github.com/pion/stun" - "github.com/pion/turn/v2/internal/proto" + "github.com/pion/stun/v3" + "github.com/pion/turn/v4/internal/proto" ) const ( maximumAllocationLifetime = time.Hour // See: https://tools.ietf.org/html/rfc5766#section-6.2 defines 3600 seconds recommendation ) -func randSeq(n int) string { - letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") - b := make([]rune, n) - for i := range b { - b[i] = letters[rand.Intn(len(letters))] //nolint:gosec - } - return string(b) -} - func buildAndSend(conn net.PacketConn, dst net.Addr, attrs ...stun.Setter) error { msg, err := stun.Build(attrs...) if err != nil { @@ -76,6 +66,13 @@ func authenticateRequest(r Request, m *stun.Message, callingMethod stun.Method) realmAttr := &stun.Realm{} badRequestMsg := buildMsg(m.TransactionID, stun.NewType(callingMethod, stun.ClassErrorResponse), &stun.ErrorCodeAttribute{Code: stun.CodeBadRequest}) + // No Auth handler is set, server is running in STUN only mode + // Respond with 400 so clients don't retry + if r.AuthHandler == nil { + sendErr := buildAndSend(r.Conn, r.SrcAddr, badRequestMsg...) + return nil, false, sendErr + } + if err := nonceAttr.GetFrom(m); err != nil { return nil, false, buildAndSendErr(r.Conn, r.SrcAddr, err, badRequestMsg...) } diff --git a/vendor/github.com/pion/turn/v2/lt_cred.go b/vendor/github.com/pion/turn/v4/lt_cred.go similarity index 51% rename from vendor/github.com/pion/turn/v2/lt_cred.go rename to vendor/github.com/pion/turn/v4/lt_cred.go index 4308ed9055..42466c3810 100644 --- a/vendor/github.com/pion/turn/v2/lt_cred.go +++ b/vendor/github.com/pion/turn/v4/lt_cred.go @@ -9,6 +9,7 @@ import ( //nolint:gci "encoding/base64" "net" "strconv" + "strings" "time" "github.com/pion/logging" @@ -22,6 +23,15 @@ func GenerateLongTermCredentials(sharedSecret string, duration time.Duration) (s return username, password, err } +// GenerateLongTermTURNRESTCredentials can be used to create credentials valid for [duration] time +func GenerateLongTermTURNRESTCredentials(sharedSecret string, user string, duration time.Duration) (string, string, error) { + t := time.Now().Add(duration).Unix() + timestamp := strconv.FormatInt(t, 10) + username := timestamp + ":" + user + password, err := longTermCredentials(username, sharedSecret) + return username, password, err +} + func longTermCredentials(username string, sharedSecret string) (string, error) { mac := hmac.New(sha1.New, []byte(sharedSecret)) _, err := mac.Write([]byte(username)) @@ -33,7 +43,7 @@ func longTermCredentials(username string, sharedSecret string) (string, error) { } // NewLongTermAuthHandler returns a turn.AuthAuthHandler used with Long Term (or Time Windowed) Credentials. -// See: https://tools.ietf.org/search/rfc5389#section-10.2 +// See: https://datatracker.ietf.org/doc/html/rfc8489#section-9.2 func NewLongTermAuthHandler(sharedSecret string, l logging.LeveledLogger) AuthHandler { if l == nil { l = logging.NewDefaultLoggerFactory().NewLogger("turn") @@ -57,3 +67,34 @@ func NewLongTermAuthHandler(sharedSecret string, l logging.LeveledLogger) AuthHa return GenerateAuthKey(username, realm, password), true } } + +// LongTermTURNRESTAuthHandler returns a turn.AuthAuthHandler that can be used to authenticate +// time-windowed ephemeral credentials generated by the TURN REST API as described in +// https://datatracker.ietf.org/doc/html/draft-uberti-behave-turn-rest-00 +// +// The supported format of is timestamp:username, where username is an arbitrary user id and the +// timestamp specifies the expiry of the credential. +func LongTermTURNRESTAuthHandler(sharedSecret string, l logging.LeveledLogger) AuthHandler { + if l == nil { + l = logging.NewDefaultLoggerFactory().NewLogger("turn") + } + return func(username, realm string, srcAddr net.Addr) (key []byte, ok bool) { + l.Tracef("Authentication username=%q realm=%q srcAddr=%v\n", username, realm, srcAddr) + timestamp := strings.Split(username, ":")[0] + t, err := strconv.Atoi(timestamp) + if err != nil { + l.Errorf("Invalid time-windowed username %q", username) + return nil, false + } + if int64(t) < time.Now().Unix() { + l.Errorf("Expired time-windowed username %q", username) + return nil, false + } + password, err := longTermCredentials(username, sharedSecret) + if err != nil { + l.Error(err.Error()) + return nil, false + } + return GenerateAuthKey(username, realm, password), true + } +} diff --git a/vendor/github.com/pion/turn/v2/relay_address_generator_none.go b/vendor/github.com/pion/turn/v4/relay_address_generator_none.go similarity index 95% rename from vendor/github.com/pion/turn/v2/relay_address_generator_none.go rename to vendor/github.com/pion/turn/v4/relay_address_generator_none.go index 3df38135a1..b0974010cd 100644 --- a/vendor/github.com/pion/turn/v2/relay_address_generator_none.go +++ b/vendor/github.com/pion/turn/v4/relay_address_generator_none.go @@ -8,8 +8,8 @@ import ( "net" "strconv" - "github.com/pion/transport/v2" - "github.com/pion/transport/v2/stdnet" + "github.com/pion/transport/v3" + "github.com/pion/transport/v3/stdnet" ) // RelayAddressGeneratorNone returns the listener with no modifications diff --git a/vendor/github.com/pion/turn/v2/relay_address_generator_range.go b/vendor/github.com/pion/turn/v4/relay_address_generator_range.go similarity index 97% rename from vendor/github.com/pion/turn/v2/relay_address_generator_range.go rename to vendor/github.com/pion/turn/v4/relay_address_generator_range.go index 9df62ccad4..d87a57f9f8 100644 --- a/vendor/github.com/pion/turn/v2/relay_address_generator_range.go +++ b/vendor/github.com/pion/turn/v4/relay_address_generator_range.go @@ -8,8 +8,8 @@ import ( "net" "github.com/pion/randutil" - "github.com/pion/transport/v2" - "github.com/pion/transport/v2/stdnet" + "github.com/pion/transport/v3" + "github.com/pion/transport/v3/stdnet" ) // RelayAddressGeneratorPortRange can be used to only allocate connections inside a defined port range. diff --git a/vendor/github.com/pion/turn/v2/relay_address_generator_static.go b/vendor/github.com/pion/turn/v4/relay_address_generator_static.go similarity index 96% rename from vendor/github.com/pion/turn/v2/relay_address_generator_static.go rename to vendor/github.com/pion/turn/v4/relay_address_generator_static.go index 6988714e00..39c6877791 100644 --- a/vendor/github.com/pion/turn/v2/relay_address_generator_static.go +++ b/vendor/github.com/pion/turn/v4/relay_address_generator_static.go @@ -8,8 +8,8 @@ import ( "net" "strconv" - "github.com/pion/transport/v2" - "github.com/pion/transport/v2/stdnet" + "github.com/pion/transport/v3" + "github.com/pion/transport/v3/stdnet" ) // RelayAddressGeneratorStatic can be used to return static IP address each time a relay is created. diff --git a/vendor/github.com/pion/turn/v2/renovate.json b/vendor/github.com/pion/turn/v4/renovate.json similarity index 100% rename from vendor/github.com/pion/turn/v2/renovate.json rename to vendor/github.com/pion/turn/v4/renovate.json diff --git a/vendor/github.com/pion/turn/v2/server.go b/vendor/github.com/pion/turn/v4/server.go similarity index 86% rename from vendor/github.com/pion/turn/v2/server.go rename to vendor/github.com/pion/turn/v4/server.go index ea8e04de5f..3b58938ff5 100644 --- a/vendor/github.com/pion/turn/v2/server.go +++ b/vendor/github.com/pion/turn/v4/server.go @@ -11,9 +11,9 @@ import ( "time" "github.com/pion/logging" - "github.com/pion/turn/v2/internal/allocation" - "github.com/pion/turn/v2/internal/proto" - "github.com/pion/turn/v2/internal/server" + "github.com/pion/turn/v4/internal/allocation" + "github.com/pion/turn/v4/internal/proto" + "github.com/pion/turn/v4/internal/server" ) const ( @@ -153,6 +153,13 @@ func (s *Server) readListener(l net.Listener, am *allocation.Manager) { go func() { s.readLoop(NewSTUNConn(conn), am) + // Delete allocation + am.DeleteAllocation(&allocation.FiveTuple{ + Protocol: allocation.UDP, // fixed UDP + SrcAddr: conn.RemoteAddr(), + DstAddr: conn.LocalAddr(), + }) + if err := conn.Close(); err != nil && !errors.Is(err, net.ErrClosed) { s.log.Errorf("Failed to close conn: %s", err) } @@ -160,10 +167,25 @@ func (s *Server) readListener(l net.Listener, am *allocation.Manager) { } } +type nilAddressGenerator struct{} + +func (n *nilAddressGenerator) Validate() error { return errRelayAddressGeneratorNil } + +func (n *nilAddressGenerator) AllocatePacketConn(string, int) (net.PacketConn, net.Addr, error) { + return nil, nil, errRelayAddressGeneratorNil +} + +func (n *nilAddressGenerator) AllocateConn(string, int) (net.Conn, net.Addr, error) { + return nil, nil, errRelayAddressGeneratorNil +} + func (s *Server) createAllocationManager(addrGenerator RelayAddressGenerator, handler PermissionHandler) (*allocation.Manager, error) { if handler == nil { handler = DefaultPermissionHandler } + if addrGenerator == nil { + addrGenerator = &nilAddressGenerator{} + } am, err := allocation.NewManager(allocation.ManagerConfig{ AllocatePacketConn: addrGenerator.AllocatePacketConn, diff --git a/vendor/github.com/pion/turn/v2/server_config.go b/vendor/github.com/pion/turn/v4/server_config.go similarity index 97% rename from vendor/github.com/pion/turn/v2/server_config.go rename to vendor/github.com/pion/turn/v4/server_config.go index ee808fe935..eaa7a2581a 100644 --- a/vendor/github.com/pion/turn/v2/server_config.go +++ b/vendor/github.com/pion/turn/v4/server_config.go @@ -57,11 +57,14 @@ func (c *PacketConnConfig) validate() error { if c.PacketConn == nil { return errConnUnset } - if c.RelayAddressGenerator == nil { - return errRelayAddressGeneratorUnset + + if c.RelayAddressGenerator != nil { + if err := c.RelayAddressGenerator.Validate(); err != nil { + return err + } } - return c.RelayAddressGenerator.Validate() + return nil } // ListenerConfig is a single net.Listener to accept connections on. This will be used for TCP, TLS and DTLS listeners diff --git a/vendor/github.com/pion/turn/v2/stun_conn.go b/vendor/github.com/pion/turn/v4/stun_conn.go similarity index 98% rename from vendor/github.com/pion/turn/v2/stun_conn.go rename to vendor/github.com/pion/turn/v4/stun_conn.go index cb062f8157..57543544ad 100644 --- a/vendor/github.com/pion/turn/v2/stun_conn.go +++ b/vendor/github.com/pion/turn/v4/stun_conn.go @@ -9,8 +9,8 @@ import ( "net" "time" - "github.com/pion/stun" - "github.com/pion/turn/v2/internal/proto" + "github.com/pion/stun/v3" + "github.com/pion/turn/v4/internal/proto" ) var ( diff --git a/vendor/github.com/pion/webrtc/v3/.golangci.yml b/vendor/github.com/pion/webrtc/v3/.golangci.yml deleted file mode 100644 index 4e3eddf429..0000000000 --- a/vendor/github.com/pion/webrtc/v3/.golangci.yml +++ /dev/null @@ -1,137 +0,0 @@ -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -linters-settings: - govet: - check-shadowing: true - misspell: - locale: US - exhaustive: - default-signifies-exhaustive: true - gomodguard: - blocked: - modules: - - github.com/pkg/errors: - recommendations: - - errors - forbidigo: - forbid: - - ^fmt.Print(f|ln)?$ - - ^log.(Panic|Fatal|Print)(f|ln)?$ - - ^os.Exit$ - - ^panic$ - - ^print(ln)?$ - -linters: - enable: - - asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers - - bidichk # Checks for dangerous unicode character sequences - - bodyclose # checks whether HTTP response body is closed successfully - - contextcheck # check the function whether use a non-inherited context - - decorder # check declaration order and count of types, constants, variables and functions - - depguard # Go linter that checks if package imports are in a list of acceptable packages - - dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) - - dupl # Tool for code clone detection - - durationcheck # check for two durations multiplied together - - errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases - - errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and optionally reports occations, where the check for the returned error can be omitted. - - errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. - - errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13. - - exhaustive # check exhaustiveness of enum switch statements - - exportloopref # checks for pointers to enclosing loop variables - - forbidigo # Forbids identifiers - - forcetypeassert # finds forced type assertions - - gci # Gci control golang package import order and make it always deterministic. - - gochecknoglobals # Checks that no globals are present in Go code - - gochecknoinits # Checks that no init functions are present in Go code - - gocognit # Computes and checks the cognitive complexity of functions - - goconst # Finds repeated strings that could be replaced by a constant - - gocritic # The most opinionated Go source code linter - - godox # Tool for detection of FIXME, TODO and other comment keywords - - goerr113 # Golang linter to check the errors handling expressions - - gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification - - gofumpt # Gofumpt checks whether code was gofumpt-ed. - - goheader # Checks is file header matches to pattern - - goimports # Goimports does everything that gofmt does. Additionally it checks unused imports - - gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. - - gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. - - goprintffuncname # Checks that printf-like functions are named with `f` at the end - - gosec # Inspects source code for security problems - - gosimple # Linter for Go source code that specializes in simplifying a code - - govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string - - grouper # An analyzer to analyze expression groups. - - importas # Enforces consistent import aliases - - ineffassign # Detects when assignments to existing variables are not used - - misspell # Finds commonly misspelled English words in comments - - nakedret # Finds naked returns in functions greater than a specified function length - - nilerr # Finds the code that returns nil even if it checks that the error is not nil. - - nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. - - noctx # noctx finds sending http request without context.Context - - predeclared # find code that shadows one of Go's predeclared identifiers - - revive # golint replacement, finds style mistakes - - staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks - - stylecheck # Stylecheck is a replacement for golint - - tagliatelle # Checks the struct tags. - - tenv # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17 - - tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes - - typecheck # Like the front-end of a Go compiler, parses and type-checks Go code - - unconvert # Remove unnecessary type conversions - - unparam # Reports unused function parameters - - unused # Checks Go code for unused constants, variables, functions and types - - wastedassign # wastedassign finds wasted assignment statements - - whitespace # Tool for detection of leading and trailing whitespace - disable: - - containedctx # containedctx is a linter that detects struct contained context.Context field - - cyclop # checks function and package cyclomatic complexity - - exhaustivestruct # Checks if all struct's fields are initialized - - funlen # Tool for detection of long functions - - gocyclo # Computes and checks the cyclomatic complexity of functions - - godot # Check if comments end in a period - - gomnd # An analyzer to detect magic numbers. - - ifshort # Checks that your code uses short syntax for if-statements whenever possible - - ireturn # Accept Interfaces, Return Concrete Types - - lll # Reports long lines - - maintidx # maintidx measures the maintainability index of each function. - - makezero # Finds slice declarations with non-zero initial length - - maligned # Tool to detect Go structs that would take less memory if their fields were sorted - - nestif # Reports deeply nested if statements - - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity - - nolintlint # Reports ill-formed or insufficient nolint directives - - paralleltest # paralleltest detects missing usage of t.Parallel() method in your Go test - - prealloc # Finds slice declarations that could potentially be preallocated - - promlinter # Check Prometheus metrics naming via promlint - - rowserrcheck # checks whether Err of rows is checked successfully - - sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed. - - testpackage # linter that makes you use a separate _test package - - thelper # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers - - varnamelen # checks that the length of a variable's name matches its scope - - wrapcheck # Checks that errors returned from external packages are wrapped - - wsl # Whitespace Linter - Forces you to use empty lines! - -issues: - exclude-use-default: false - exclude-rules: - # Allow complex tests, better to be self contained - - path: _test\.go - linters: - - gocognit - - forbidigo - - # Allow complex main function in examples - - path: examples - text: "of func `main` is high" - linters: - - gocognit - - # Allow forbidden identifiers in examples - - path: examples - linters: - - forbidigo - - # Allow forbidden identifiers in CLI commands - - path: cmd - linters: - - forbidigo - -run: - skip-dirs-use-default: false diff --git a/vendor/github.com/pion/webrtc/v3/AUTHORS.txt b/vendor/github.com/pion/webrtc/v3/AUTHORS.txt deleted file mode 100644 index 799ddfc2b6..0000000000 --- a/vendor/github.com/pion/webrtc/v3/AUTHORS.txt +++ /dev/null @@ -1,229 +0,0 @@ -# Thank you to everyone that made Pion possible. If you are interested in contributing -# we would love to have you https://github.com/pion/webrtc/wiki/Contributing -# -# This file is auto generated, using git to list all individuals contributors. -# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting -a-wing <1@233.email> -Aaron Boushley -Aaron France -Adam Kiss -Aditya Kumar -Adrian Cable -adwpc -aggresss -akil -Aleksandr Alekseev -Aleksandr Razumov -aler9 <46489434+aler9@users.noreply.github.com> -Alex Browne -Alex Harford -Alexey Khit -AlexWoo(武杰) -Ali Error -Andrew N. Shalaev -Antoine Baché -Antoine Baché -Anton -Artur Shellunts -Assad Obaid -Ato Araki -Atsushi Watanabe -backkem -baiyufei -Bao Nguyen -Ben Weitzman -Benny Daon -bkim -Bo Shi -boks1971 -Brendan Rius -brian -Bryan Phelps -Cameron Elliott -Cecylia Bocovich -Cedric Fung -cgojin -Chad Retz -chenkaiC4 -Chinmay Kousik -Chris Hiszpanski -Christopher Fry -Clayton McCray -cnderrauber -cyannuk -Daniele Sluijters -David -David Hamilton -David Zhao -David Zhao -david.s -Dean Sheather -decanus <7621705+decanus@users.noreply.github.com> -Denis -digitalix -do-hyung-kim -donotanswer -earle -Egon Elbre -Eric Daniels -Eric Fontaine -Evan Sonderegger -feixiao -Forest Johnson -frank -funvit -Gabor Pongracz -Gareth Hayes -Guilherme -Guillaume Denis -Hanjun Kim -Hans Gylling -Hao -Hendrik Hofstadt -Henry -Hongchao Ma -Hugo Arregui -Hugo Arregui -Ilya Mayorov -imalic3 -Ivan Egorov -JacobZwang <59858341+JacobZwang@users.noreply.github.com> -Jake B -Jamie Good -Jason -Jeff Tchang -jeremija -Jerko Steiner -Jerry Tao -jinleileiking -John Berthels -John Bradley -John Selbie -JooYoung -Jorropo -Josh Bleecher Snyder -juberti -Juliusz Chroboczek -Justin Okamoto -Justin Okamoto -Kevin -Kevin Staunton-Lambert -Kevin Wang -Konstantin Chugalinskiy -Konstantin Itskov -krishna chiatanya -Kunal -Kunal Singh -Kuzmin Vladimir -lawl -Len -Leslie Wang -lisa yan -Lukas Herman -Luke -Luke Curley -Luke S -Magnus Wahlstrand -Manish -Markus Tzoe -Marouane <6729798+nindolabs@users.noreply.github.com> -Marouane -Masahiro Nakamura <13937915+tsuu32@users.noreply.github.com> -Mathis Engelbart -Max Hawkins -mchlrhw <4028654+mchlrhw@users.noreply.github.com> -Michael MacDonald -Michael MacDonald -Michiel De Backker <38858977+backkem@users.noreply.github.com> -Mike Coleman -Mindgamesnl -mission-liao -mohammadne -mr-shitij <21.shitijagrawal@gmail.com> -mxmCherry -Nam V. Do -Nick Mykins -Nicolas Menard -nindolabs <6729798+nindolabs@users.noreply.github.com> -Norman Rasmussen -notedit -o0olele -obasajujoshua31 -Oleg Kovalov -opennota -OrlandoCo -Pascal Benoit -pascal-ace <47424881+pascal-ace@users.noreply.github.com> -Patrice Ferlet -Patrick Lange -Patryk Rogalski -Pieere Pi -Pouget-Abadie -q191201771 <191201771@qq.com> -Quentin Renard -Rafael Viscarra -rahulnakre -Raphael Randschau -Raphael Randschau -Reese <3253971+figadore@users.noreply.github.com> -rob -rob-deutsch -Robert Eperjesi -Robin Raymond -Roman Romanenko -Roman Romanenko -ronan -Ryan Shumate -salmān aljammāz -Sam Lancia -Sean -Sean DuBois -Sean DuBois -Sean DuBois -Sean DuBois -Sean DuBois -Sean DuBois -Sean Knight -Sebastian Waisbrot -Sidney San Martín -Simon Cousineau -Simon Eisenmann -simonacca-fotokite <47634061+simonacca-fotokite@users.noreply.github.com> -Simone Gotti -Slugalisk -Somers Matthews -soolaugust -spaceCh1mp -Steffen Vogel -stephanrotolante -streamer45 -Suhas Gaddam -Suzuki Takeo -sylba2050 -Tarrence van As -tarrencev -Thomas Miller -Tobias Fridén -Tomek -treyhakanson -Tristan Matthews -Twometer -Vicken Simonian -wattanakorn495 -Will Forcey -Will Watson -WofWca -Woodrow Douglass -xsbchen -Yoon SeungYong -Yuki Igarashi -yusuke -Yutaka Takeda -ZHENK -zhngs -zigazeljko -Štefan Uram -박종훈 - -# List of contributors not appearing in Git history - diff --git a/vendor/github.com/pion/webrtc/v3/package.json b/vendor/github.com/pion/webrtc/v3/package.json deleted file mode 100644 index 429f3efb34..0000000000 --- a/vendor/github.com/pion/webrtc/v3/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "webrtc", - "repository": "git@github.com:pion/webrtc.git", - "private": true, - "devDependencies": { - "wrtc": "0.4.7" - }, - "dependencies": { - "request": "2.88.2" - } -} diff --git a/vendor/github.com/pion/webrtc/v3/yarn.lock b/vendor/github.com/pion/webrtc/v3/yarn.lock deleted file mode 100644 index 01bf7823dc..0000000000 --- a/vendor/github.com/pion/webrtc/v3/yarn.lock +++ /dev/null @@ -1,797 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -ajv@^6.5.5: - version "6.12.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd" - integrity sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -aproba@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - -are-we-there-yet@~1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.0.tgz#a17b3a8ea811060e74d47d306122400ad4497ae2" - integrity sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA== - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -chownr@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" - integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - -combined-stream@^1.0.6, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= - -core-util-is@1.0.2, core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -debug@^2.1.2: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= - -detect-libc@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= - -domexception@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" - integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== - dependencies: - webidl-conversions "^4.0.2" - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -fast-deep-equal@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" - integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -fs-minipass@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" - integrity sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ== - dependencies: - minipass "^2.2.1" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - -glob@^7.1.3: - version "7.1.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" - integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" - integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== - dependencies: - ajv "^6.5.5" - har-schema "^2.0.0" - -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -iconv-lite@^0.4.4: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ignore-walk@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" - integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== - dependencies: - minimatch "^3.0.4" - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - -ini@~1.3.0: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -mime-db@1.44.0: - version "1.44.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" - integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== - -mime-types@^2.1.12, mime-types@~2.1.19: - version "2.1.27" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" - integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== - dependencies: - mime-db "1.44.0" - -minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - -minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= - -minipass@^2.2.1, minipass@^2.3.4: - version "2.3.5" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" - integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - -minizlib@^1.1.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" - integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== - dependencies: - minipass "^2.2.1" - -mkdirp@^0.5.0, mkdirp@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= - dependencies: - minimist "0.0.8" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -needle@^2.2.1: - version "2.2.4" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" - integrity sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA== - dependencies: - debug "^2.1.2" - iconv-lite "^0.4.4" - sax "^1.2.4" - -node-pre-gyp@^0.13.0: - version "0.13.0" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.13.0.tgz#df9ab7b68dd6498137717838e4f92a33fc9daa42" - integrity sha512-Md1D3xnEne8b/HGVQkZZwV27WUi1ZRuZBij24TNaZwUPU3ZAFtvT6xxJGaUVillfmMKnn5oD1HoGsp2Ftik7SQ== - dependencies: - detect-libc "^1.0.2" - mkdirp "^0.5.1" - needle "^2.2.1" - nopt "^4.0.1" - npm-packlist "^1.1.6" - npmlog "^4.0.2" - rc "^1.2.7" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^4" - -nopt@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" - integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= - dependencies: - abbrev "1" - osenv "^0.1.4" - -npm-bundled@^1.0.1: - version "1.0.6" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" - integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g== - -npm-packlist@^1.1.6: - version "1.4.1" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.1.tgz#19064cdf988da80ea3cee45533879d90192bbfbc" - integrity sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw== - dependencies: - ignore-walk "^3.0.1" - npm-bundled "^1.0.1" - -npmlog@^4.0.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - -os-tmpdir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -osenv@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - -process-nextick-args@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" - integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== - -psl@^1.1.28: - version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== - -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== - -rc@^1.2.7: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -readable-stream@^2.0.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -request@2.88.2: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -rimraf@^2.6.1: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== - dependencies: - glob "^7.1.3" - -safe-buffer@^5.0.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sax@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - -semver@^5.3.0: - version "5.6.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" - integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== - -set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -signal-exit@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= - -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2": - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - -tar@^4: - version "4.4.8" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" - integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ== - dependencies: - chownr "^1.1.1" - fs-minipass "^1.2.5" - minipass "^2.3.4" - minizlib "^1.1.1" - mkdirp "^0.5.0" - safe-buffer "^5.1.2" - yallist "^3.0.2" - -tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - -uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== - dependencies: - punycode "^2.1.0" - -util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -webidl-conversions@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" - integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== - -wide-align@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -wrtc@0.4.7: - version "0.4.7" - resolved "https://registry.yarnpkg.com/wrtc/-/wrtc-0.4.7.tgz#c61530cd662713e50bffe64b7a78673ce070426c" - integrity sha512-P6Hn7VT4lfSH49HxLHcHhDq+aFf/jd9dPY7lDHeFhZ22N3858EKuwm2jmnlPzpsRGEPaoF6XwkcxY5SYnt4f/g== - dependencies: - node-pre-gyp "^0.13.0" - optionalDependencies: - domexception "^1.0.1" - -yallist@^3.0.0, yallist@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" - integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== diff --git a/vendor/github.com/pion/webrtc/v3/.codacy.yaml b/vendor/github.com/pion/webrtc/v4/.codacy.yaml similarity index 100% rename from vendor/github.com/pion/webrtc/v3/.codacy.yaml rename to vendor/github.com/pion/webrtc/v4/.codacy.yaml diff --git a/vendor/github.com/pion/webrtc/v3/.eslintrc.json b/vendor/github.com/pion/webrtc/v4/.eslintrc.json similarity index 100% rename from vendor/github.com/pion/webrtc/v3/.eslintrc.json rename to vendor/github.com/pion/webrtc/v4/.eslintrc.json diff --git a/vendor/github.com/pion/webrtc/v3/.gitignore b/vendor/github.com/pion/webrtc/v4/.gitignore similarity index 100% rename from vendor/github.com/pion/webrtc/v3/.gitignore rename to vendor/github.com/pion/webrtc/v4/.gitignore diff --git a/vendor/github.com/pion/webrtc/v4/.golangci.yml b/vendor/github.com/pion/webrtc/v4/.golangci.yml new file mode 100644 index 0000000000..a3235bec28 --- /dev/null +++ b/vendor/github.com/pion/webrtc/v4/.golangci.yml @@ -0,0 +1,125 @@ +# SPDX-FileCopyrightText: 2023 The Pion community +# SPDX-License-Identifier: MIT + +run: + timeout: 5m + +linters-settings: + govet: + enable: + - shadow + misspell: + locale: US + exhaustive: + default-signifies-exhaustive: true + gomodguard: + blocked: + modules: + - github.com/pkg/errors: + recommendations: + - errors + forbidigo: + forbid: + - ^fmt.Print(f|ln)?$ + - ^log.(Panic|Fatal|Print)(f|ln)?$ + - ^os.Exit$ + - ^panic$ + - ^print(ln)?$ + +linters: + enable: + - asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers + - bidichk # Checks for dangerous unicode character sequences + - bodyclose # checks whether HTTP response body is closed successfully + - contextcheck # check the function whether use a non-inherited context + - decorder # check declaration order and count of types, constants, variables and functions + - dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) + - dupl # Tool for code clone detection + - durationcheck # check for two durations multiplied together + - errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases + - errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and optionally reports occations, where the check for the returned error can be omitted. + - errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. + - errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13. + - exhaustive # check exhaustiveness of enum switch statements + - exportloopref # checks for pointers to enclosing loop variables + - forbidigo # Forbids identifiers + - forcetypeassert # finds forced type assertions + - gci # Gci control golang package import order and make it always deterministic. + - gochecknoglobals # Checks that no globals are present in Go code + - gochecknoinits # Checks that no init functions are present in Go code + - gocognit # Computes and checks the cognitive complexity of functions + - goconst # Finds repeated strings that could be replaced by a constant + - gocritic # The most opinionated Go source code linter + - godox # Tool for detection of FIXME, TODO and other comment keywords + - err113 # Golang linter to check the errors handling expressions + - gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification + - gofumpt # Gofumpt checks whether code was gofumpt-ed. + - goheader # Checks is file header matches to pattern + - goimports # Goimports does everything that gofmt does. Additionally it checks unused imports + - gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. + - gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. + - goprintffuncname # Checks that printf-like functions are named with `f` at the end + - gosec # Inspects source code for security problems + - gosimple # Linter for Go source code that specializes in simplifying a code + - govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string + - grouper # An analyzer to analyze expression groups. + - importas # Enforces consistent import aliases + - ineffassign # Detects when assignments to existing variables are not used + - misspell # Finds commonly misspelled English words in comments + - nilerr # Finds the code that returns nil even if it checks that the error is not nil. + - nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. + - noctx # noctx finds sending http request without context.Context + - predeclared # find code that shadows one of Go's predeclared identifiers + - revive # golint replacement, finds style mistakes + - staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks + - stylecheck # Stylecheck is a replacement for golint + - tagliatelle # Checks the struct tags. + - tenv # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17 + - tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes + - typecheck # Like the front-end of a Go compiler, parses and type-checks Go code + - unconvert # Remove unnecessary type conversions + - unparam # Reports unused function parameters + - unused # Checks Go code for unused constants, variables, functions and types + - wastedassign # wastedassign finds wasted assignment statements + - whitespace # Tool for detection of leading and trailing whitespace + disable: + - depguard # Go linter that checks if package imports are in a list of acceptable packages + - containedctx # containedctx is a linter that detects struct contained context.Context field + - cyclop # checks function and package cyclomatic complexity + - funlen # Tool for detection of long functions + - gocyclo # Computes and checks the cyclomatic complexity of functions + - godot # Check if comments end in a period + - gomnd # An analyzer to detect magic numbers. + - ireturn # Accept Interfaces, Return Concrete Types + - lll # Reports long lines + - maintidx # maintidx measures the maintainability index of each function. + - makezero # Finds slice declarations with non-zero initial length + - nakedret # Finds naked returns in functions greater than a specified function length + - nestif # Reports deeply nested if statements + - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity + - nolintlint # Reports ill-formed or insufficient nolint directives + - paralleltest # paralleltest detects missing usage of t.Parallel() method in your Go test + - prealloc # Finds slice declarations that could potentially be preallocated + - promlinter # Check Prometheus metrics naming via promlint + - rowserrcheck # checks whether Err of rows is checked successfully + - sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed. + - testpackage # linter that makes you use a separate _test package + - thelper # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers + - varnamelen # checks that the length of a variable's name matches its scope + - wrapcheck # Checks that errors returned from external packages are wrapped + - wsl # Whitespace Linter - Forces you to use empty lines! + +issues: + exclude-use-default: false + exclude-dirs-use-default: false + exclude-rules: + # Allow complex tests and examples, better to be self contained + - path: (examples|main\.go|_test\.go) + linters: + - forbidigo + - gocognit + + # Allow forbidden identifiers in CLI commands + - path: cmd + linters: + - forbidigo diff --git a/vendor/github.com/pion/webrtc/v3/.goreleaser.yml b/vendor/github.com/pion/webrtc/v4/.goreleaser.yml similarity index 100% rename from vendor/github.com/pion/webrtc/v3/.goreleaser.yml rename to vendor/github.com/pion/webrtc/v4/.goreleaser.yml diff --git a/vendor/github.com/pion/webrtc/v3/DESIGN.md b/vendor/github.com/pion/webrtc/v4/DESIGN.md similarity index 97% rename from vendor/github.com/pion/webrtc/v3/DESIGN.md rename to vendor/github.com/pion/webrtc/v4/DESIGN.md index e22b08e301..45ca1ac0e2 100644 --- a/vendor/github.com/pion/webrtc/v3/DESIGN.md +++ b/vendor/github.com/pion/webrtc/v4/DESIGN.md @@ -19,7 +19,7 @@ When possible we leave all decisions to the user. When choice is possible (like If you know how to use WebRTC in your browser, you know how to use Pion WebRTC. We try our best just to duplicate the Javascript API, so your code can look the same everywhere. -If this is your first time using WebRTC, don't worry! We have multiple [examples](https://github.com/pion/webrtc/tree/master/examples) and [GoDoc](https://pkg.go.dev/github.com/pion/webrtc/v3) +If this is your first time using WebRTC, don't worry! We have multiple [examples](https://github.com/pion/webrtc/tree/master/examples) and [GoDoc](https://pkg.go.dev/github.com/pion/webrtc/v4) ### Bring your own media Pion WebRTC doesn't make any assumptions about where your audio, video or text come from. You can use FFmpeg, GStreamer, MLT or just serve a video file. diff --git a/vendor/github.com/pion/webrtc/v3/LICENSE b/vendor/github.com/pion/webrtc/v4/LICENSE similarity index 100% rename from vendor/github.com/pion/webrtc/v3/LICENSE rename to vendor/github.com/pion/webrtc/v4/LICENSE diff --git a/vendor/github.com/pion/webrtc/v3/README.md b/vendor/github.com/pion/webrtc/v4/README.md similarity index 88% rename from vendor/github.com/pion/webrtc/v3/README.md rename to vendor/github.com/pion/webrtc/v4/README.md index 80dd8c1234..1099cb25c9 100644 --- a/vendor/github.com/pion/webrtc/v3/README.md +++ b/vendor/github.com/pion/webrtc/v4/README.md @@ -13,15 +13,25 @@
GitHub Workflow Status - Go Reference + Go Reference Coverage Status - Go Report Card + Go Report Card License: MIT


+### New Release + +Pion WebRTC v4.0.0 has been released! See the [release notes](https://github.com/pion/webrtc/wiki/Release-WebRTC@v4.0.0) to learn about new features and breaking changes. + +If you aren't able to upgrade yet check the [tags](https://github.com/pion/webrtc/tags) for the latest `v3` release. + +We would love your feedback! Please create GitHub issues or join [the Slack channel](https://pion.ly/slack) to follow development and speak with the maintainers. + +----- + ### Usage -[Go Modules](https://blog.golang.org/using-go-modules) are mandatory for using Pion WebRTC. So make sure you set `export GO111MODULE=on`, and explicitly specify `/v2` or `/v3` when importing. +[Go Modules](https://blog.golang.org/using-go-modules) are mandatory for using Pion WebRTC. So make sure you set `export GO111MODULE=on`, and explicitly specify `/v4` (or an earlier version) when importing. **[example applications](examples/README.md)** contains code samples of common things people build with Pion WebRTC. @@ -30,7 +40,7 @@ **[awesome-pion](https://github.com/pion/awesome-pion)** contains projects that have used Pion, and serve as real world examples of usage. -**[GoDoc](https://pkg.go.dev/github.com/pion/webrtc/v3)** is an auto generated API reference. All our Public APIs are commented. +**[GoDoc](https://pkg.go.dev/github.com/pion/webrtc/v4)** is an auto generated API reference. All our Public APIs are commented. **[FAQ](https://github.com/pion/webrtc/wiki/FAQ)** has answers to common questions. If you have a question not covered please ask in [Slack](https://pion.ly/slack) we are always looking to expand it. @@ -60,7 +70,7 @@ This book is vendor agnostic and will not have any Pion specific information. * Send/Receive audio and video * Renegotiation * Plan-B and Unified Plan -* [SettingEngine](https://pkg.go.dev/github.com/pion/webrtc/v3#SettingEngine) for Pion specific extensions +* [SettingEngine](https://pkg.go.dev/github.com/pion/webrtc/v4#SettingEngine) for Pion specific extensions #### Connectivity @@ -123,7 +133,7 @@ We are always looking to support **your projects**. Please reach out if you have If you need commercial support or don't want to use public methods you can contact us at [team@pion.ly](mailto:team@pion.ly) ### Contributing -Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible: [AUTHORS.txt](./AUTHORS.txt) +Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible ### License MIT License - see [LICENSE](LICENSE) for full text diff --git a/vendor/github.com/pion/webrtc/v3/api.go b/vendor/github.com/pion/webrtc/v4/api.go similarity index 73% rename from vendor/github.com/pion/webrtc/v3/api.go rename to vendor/github.com/pion/webrtc/v4/api.go index 716be1f380..369b1a9a37 100644 --- a/vendor/github.com/pion/webrtc/v3/api.go +++ b/vendor/github.com/pion/webrtc/v4/api.go @@ -25,12 +25,13 @@ type API struct { } // NewAPI Creates a new API object for keeping semi-global settings to WebRTC objects +// +// It uses the default Codecs and Interceptors unless you customize them +// using WithMediaEngine and WithInterceptorRegistry respectively. func NewAPI(options ...func(*API)) *API { a := &API{ - interceptor: &interceptor.NoOp{}, - settingEngine: &SettingEngine{}, - mediaEngine: &MediaEngine{}, - interceptorRegistry: &interceptor.Registry{}, + interceptor: &interceptor.NoOp{}, + settingEngine: &SettingEngine{}, } for _, o := range options { @@ -41,6 +42,24 @@ func NewAPI(options ...func(*API)) *API { a.settingEngine.LoggerFactory = logging.NewDefaultLoggerFactory() } + logger := a.settingEngine.LoggerFactory.NewLogger("api") + + if a.mediaEngine == nil { + a.mediaEngine = &MediaEngine{} + err := a.mediaEngine.RegisterDefaultCodecs() + if err != nil { + logger.Errorf("Failed to register default codecs %s", err) + } + } + + if a.interceptorRegistry == nil { + a.interceptorRegistry = &interceptor.Registry{} + err := RegisterDefaultInterceptors(a.mediaEngine, a.interceptorRegistry) + if err != nil { + logger.Errorf("Failed to register default interceptors %s", err) + } + } + return a } diff --git a/vendor/github.com/pion/webrtc/v3/api_js.go b/vendor/github.com/pion/webrtc/v4/api_js.go similarity index 91% rename from vendor/github.com/pion/webrtc/v3/api_js.go rename to vendor/github.com/pion/webrtc/v4/api_js.go index fe94bff1fb..1f0fcb74c2 100644 --- a/vendor/github.com/pion/webrtc/v3/api_js.go +++ b/vendor/github.com/pion/webrtc/v4/api_js.go @@ -6,7 +6,7 @@ package webrtc -// API bundles the global funcions of the WebRTC and ORTC API. +// API bundles the global functions of the WebRTC and ORTC API. type API struct { settingEngine *SettingEngine } diff --git a/vendor/github.com/pion/webrtc/v3/atomicbool.go b/vendor/github.com/pion/webrtc/v4/atomicbool.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/atomicbool.go rename to vendor/github.com/pion/webrtc/v4/atomicbool.go diff --git a/vendor/github.com/pion/webrtc/v3/bundlepolicy.go b/vendor/github.com/pion/webrtc/v4/bundlepolicy.go similarity index 93% rename from vendor/github.com/pion/webrtc/v3/bundlepolicy.go rename to vendor/github.com/pion/webrtc/v4/bundlepolicy.go index ea6dad5aeb..7e3d6c506f 100644 --- a/vendor/github.com/pion/webrtc/v3/bundlepolicy.go +++ b/vendor/github.com/pion/webrtc/v4/bundlepolicy.go @@ -14,11 +14,14 @@ import ( type BundlePolicy int const ( + // BundlePolicyUnknown is the enum's zero-value + BundlePolicyUnknown BundlePolicy = iota + // BundlePolicyBalanced indicates to gather ICE candidates for each // media type in use (audio, video, and data). If the remote endpoint is // not bundle-aware, negotiate only one audio and video track on separate // transports. - BundlePolicyBalanced BundlePolicy = iota + 1 + BundlePolicyBalanced // BundlePolicyMaxCompat indicates to gather ICE candidates for each // track. If the remote endpoint is not bundle-aware, negotiate all media @@ -47,7 +50,7 @@ func newBundlePolicy(raw string) BundlePolicy { case bundlePolicyMaxBundleStr: return BundlePolicyMaxBundle default: - return BundlePolicy(Unknown) + return BundlePolicyUnknown } } diff --git a/vendor/github.com/pion/webrtc/v3/certificate.go b/vendor/github.com/pion/webrtc/v4/certificate.go similarity index 98% rename from vendor/github.com/pion/webrtc/v3/certificate.go rename to vendor/github.com/pion/webrtc/v4/certificate.go index 1d5631bc48..36d1fb0796 100644 --- a/vendor/github.com/pion/webrtc/v3/certificate.go +++ b/vendor/github.com/pion/webrtc/v4/certificate.go @@ -20,8 +20,8 @@ import ( "strings" "time" - "github.com/pion/dtls/v2/pkg/crypto/fingerprint" - "github.com/pion/webrtc/v3/pkg/rtcerr" + "github.com/pion/dtls/v3/pkg/crypto/fingerprint" + "github.com/pion/webrtc/v4/pkg/rtcerr" ) // Certificate represents a x509Cert used to authenticate WebRTC communications. diff --git a/vendor/github.com/pion/webrtc/v3/codecov.yml b/vendor/github.com/pion/webrtc/v4/codecov.yml similarity index 100% rename from vendor/github.com/pion/webrtc/v3/codecov.yml rename to vendor/github.com/pion/webrtc/v4/codecov.yml diff --git a/vendor/github.com/pion/webrtc/v3/configuration.go b/vendor/github.com/pion/webrtc/v4/configuration.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/configuration.go rename to vendor/github.com/pion/webrtc/v4/configuration.go diff --git a/vendor/github.com/pion/webrtc/v3/configuration_common.go b/vendor/github.com/pion/webrtc/v4/configuration_common.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/configuration_common.go rename to vendor/github.com/pion/webrtc/v4/configuration_common.go diff --git a/vendor/github.com/pion/webrtc/v3/configuration_js.go b/vendor/github.com/pion/webrtc/v4/configuration_js.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/configuration_js.go rename to vendor/github.com/pion/webrtc/v4/configuration_js.go diff --git a/vendor/github.com/pion/webrtc/v3/constants.go b/vendor/github.com/pion/webrtc/v4/constants.go similarity index 89% rename from vendor/github.com/pion/webrtc/v3/constants.go rename to vendor/github.com/pion/webrtc/v4/constants.go index c8ebb7bf5b..f248342b39 100644 --- a/vendor/github.com/pion/webrtc/v3/constants.go +++ b/vendor/github.com/pion/webrtc/v4/constants.go @@ -3,14 +3,9 @@ package webrtc -import "github.com/pion/dtls/v2" +import "github.com/pion/dtls/v3" const ( - // Unknown defines default public constant to use for "enum" like struct - // comparisons when no value was defined. - Unknown = iota - unknownStr = "unknown" - // Equal to UDP MTU receiveMTU = 1460 diff --git a/vendor/github.com/pion/webrtc/v3/datachannel.go b/vendor/github.com/pion/webrtc/v4/datachannel.go similarity index 95% rename from vendor/github.com/pion/webrtc/v3/datachannel.go rename to vendor/github.com/pion/webrtc/v4/datachannel.go index c3ce10b9e3..218ebfbec0 100644 --- a/vendor/github.com/pion/webrtc/v3/datachannel.go +++ b/vendor/github.com/pion/webrtc/v4/datachannel.go @@ -17,7 +17,7 @@ import ( "github.com/pion/datachannel" "github.com/pion/logging" - "github.com/pion/webrtc/v3/pkg/rtcerr" + "github.com/pion/webrtc/v4/pkg/rtcerr" ) const dataChannelBufferSize = math.MaxUint16 // message size limit for Chromium @@ -242,7 +242,7 @@ func (d *DataChannel) onOpen() { } // OnDial sets an event handler which is invoked when the -// peer has been dialed, but before said peer has responsed +// peer has been dialed, but before said peer has responded func (d *DataChannel) OnDial(f func()) { d.mu.Lock() d.dialHandlerOnce = sync.Once{} @@ -380,12 +380,6 @@ func (d *DataChannel) onError(err error) { } } -// See https://github.com/pion/webrtc/issues/1516 -// nolint:gochecknoglobals -var rlBufPool = sync.Pool{New: func() interface{} { - return make([]byte, dataChannelBufferSize) -}} - func (d *DataChannel) readLoop() { defer func() { d.mu.Lock() @@ -393,11 +387,10 @@ func (d *DataChannel) readLoop() { d.mu.Unlock() defer close(readLoopActive) }() + buffer := make([]byte, dataChannelBufferSize) for { - buffer := rlBufPool.Get().([]byte) //nolint:forcetypeassert n, isString, err := d.dataChannel.ReadDataChannel(buffer) if err != nil { - rlBufPool.Put(buffer) // nolint:staticcheck d.setReadyState(DataChannelStateClosed) if !errors.Is(err, io.EOF) { d.onError(err) @@ -408,8 +401,6 @@ func (d *DataChannel) readLoop() { m := DataChannelMessage{Data: make([]byte, n), IsString: isString} copy(m.Data, buffer[:n]) - // The 'staticcheck' pragma is a false positive on the part of the CI linter. - rlBufPool.Put(buffer) // nolint:staticcheck // NB: Why was DataChannelMessage not passed as a pointer value? d.onMessage(m) // nolint:staticcheck @@ -457,7 +448,6 @@ func (d *DataChannel) ensureOpen() error { // resulting DataChannel object. func (d *DataChannel) Detach() (datachannel.ReadWriteCloser, error) { d.mu.Lock() - defer d.mu.Unlock() if !d.api.settingEngine.detach.DataChannels { return nil, errDetachNotEnabled @@ -469,7 +459,28 @@ func (d *DataChannel) Detach() (datachannel.ReadWriteCloser, error) { d.detachCalled = true - return d.dataChannel, nil + dataChannel := d.dataChannel + d.mu.Unlock() + + // Remove the reference from SCTPTransport so that the datachannel + // can be garbage collected on close + d.sctpTransport.lock.Lock() + n := len(d.sctpTransport.dataChannels) + j := 0 + for i := 0; i < n; i++ { + if d == d.sctpTransport.dataChannels[i] { + continue + } + d.sctpTransport.dataChannels[j] = d.sctpTransport.dataChannels[i] + j++ + } + for i := j; i < n; i++ { + d.sctpTransport.dataChannels[i] = nil + } + d.sctpTransport.dataChannels = d.sctpTransport.dataChannels[:j] + d.sctpTransport.lock.Unlock() + + return dataChannel, nil } // Close Closes the DataChannel. It may be called regardless of whether @@ -642,7 +653,7 @@ func (d *DataChannel) SetBufferedAmountLowThreshold(th uint64) { } // OnBufferedAmountLow sets an event handler which is invoked when -// the number of bytes of outgoing data becomes lower than the +// the number of bytes of outgoing data becomes lower than or equal to the // BufferedAmountLowThreshold. func (d *DataChannel) OnBufferedAmountLow(f func()) { d.mu.Lock() diff --git a/vendor/github.com/pion/webrtc/v3/datachannel_js.go b/vendor/github.com/pion/webrtc/v4/datachannel_js.go similarity index 98% rename from vendor/github.com/pion/webrtc/v3/datachannel_js.go rename to vendor/github.com/pion/webrtc/v4/datachannel_js.go index a34ab6efde..5e5fc4b0cd 100644 --- a/vendor/github.com/pion/webrtc/v3/datachannel_js.go +++ b/vendor/github.com/pion/webrtc/v4/datachannel_js.go @@ -115,7 +115,7 @@ func (d *DataChannel) SendText(s string) (err error) { // Before calling Detach you have to enable this behavior by calling // webrtc.DetachDataChannels(). Combining detached and normal data channels // is not supported. -// Please reffer to the data-channels-detach example and the +// Please refer to the data-channels-detach example and the // pion/datachannel documentation for the correct way to handle the // resulting DataChannel object. func (d *DataChannel) Detach() (datachannel.ReadWriteCloser, error) { @@ -246,7 +246,7 @@ func (d *DataChannel) SetBufferedAmountLowThreshold(th uint64) { } // OnBufferedAmountLow sets an event handler which is invoked when -// the number of bytes of outgoing data becomes lower than the +// the number of bytes of outgoing data becomes lower than or equal to the // BufferedAmountLowThreshold. func (d *DataChannel) OnBufferedAmountLow(f func()) { if d.onBufferedAmountLow != nil { diff --git a/vendor/github.com/pion/webrtc/v3/datachannel_js_detach.go b/vendor/github.com/pion/webrtc/v4/datachannel_js_detach.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/datachannel_js_detach.go rename to vendor/github.com/pion/webrtc/v4/datachannel_js_detach.go diff --git a/vendor/github.com/pion/webrtc/v3/datachannelinit.go b/vendor/github.com/pion/webrtc/v4/datachannelinit.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/datachannelinit.go rename to vendor/github.com/pion/webrtc/v4/datachannelinit.go diff --git a/vendor/github.com/pion/webrtc/v3/datachannelmessage.go b/vendor/github.com/pion/webrtc/v4/datachannelmessage.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/datachannelmessage.go rename to vendor/github.com/pion/webrtc/v4/datachannelmessage.go diff --git a/vendor/github.com/pion/webrtc/v3/datachannelparameters.go b/vendor/github.com/pion/webrtc/v4/datachannelparameters.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/datachannelparameters.go rename to vendor/github.com/pion/webrtc/v4/datachannelparameters.go diff --git a/vendor/github.com/pion/webrtc/v3/datachannelstate.go b/vendor/github.com/pion/webrtc/v4/datachannelstate.go similarity index 92% rename from vendor/github.com/pion/webrtc/v3/datachannelstate.go rename to vendor/github.com/pion/webrtc/v4/datachannelstate.go index 55dc916e97..848d94ca89 100644 --- a/vendor/github.com/pion/webrtc/v3/datachannelstate.go +++ b/vendor/github.com/pion/webrtc/v4/datachannelstate.go @@ -7,10 +7,13 @@ package webrtc type DataChannelState int const ( + // DataChannelStateUnknown is the enum's zero-value + DataChannelStateUnknown DataChannelState = iota + // DataChannelStateConnecting indicates that the data channel is being // established. This is the initial state of DataChannel, whether created // with CreateDataChannel, or dispatched as a part of an DataChannelEvent. - DataChannelStateConnecting DataChannelState = iota + 1 + DataChannelStateConnecting // DataChannelStateOpen indicates that the underlying data transport is // established and communication is possible. @@ -44,7 +47,7 @@ func newDataChannelState(raw string) DataChannelState { case dataChannelStateClosedStr: return DataChannelStateClosed default: - return DataChannelState(Unknown) + return DataChannelStateUnknown } } diff --git a/vendor/github.com/pion/webrtc/v3/dtlsfingerprint.go b/vendor/github.com/pion/webrtc/v4/dtlsfingerprint.go similarity index 88% rename from vendor/github.com/pion/webrtc/v3/dtlsfingerprint.go rename to vendor/github.com/pion/webrtc/v4/dtlsfingerprint.go index b0d061481a..b1bf773bcf 100644 --- a/vendor/github.com/pion/webrtc/v3/dtlsfingerprint.go +++ b/vendor/github.com/pion/webrtc/v4/dtlsfingerprint.go @@ -6,7 +6,7 @@ package webrtc // DTLSFingerprint specifies the hash function algorithm and certificate // fingerprint as described in https://tools.ietf.org/html/rfc4572. type DTLSFingerprint struct { - // Algorithm specifies one of the the hash function algorithms defined in + // Algorithm specifies one of the hash function algorithms defined in // the 'Hash function Textual Names' registry. Algorithm string `json:"algorithm"` diff --git a/vendor/github.com/pion/webrtc/v3/dtlsparameters.go b/vendor/github.com/pion/webrtc/v4/dtlsparameters.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/dtlsparameters.go rename to vendor/github.com/pion/webrtc/v4/dtlsparameters.go diff --git a/vendor/github.com/pion/webrtc/v3/dtlsrole.go b/vendor/github.com/pion/webrtc/v4/dtlsrole.go similarity index 95% rename from vendor/github.com/pion/webrtc/v3/dtlsrole.go rename to vendor/github.com/pion/webrtc/v4/dtlsrole.go index 9cee581d9e..40a14e8721 100644 --- a/vendor/github.com/pion/webrtc/v3/dtlsrole.go +++ b/vendor/github.com/pion/webrtc/v4/dtlsrole.go @@ -11,10 +11,13 @@ import ( type DTLSRole byte const ( + // DTLSRoleUnknown is the enum's zero-value + DTLSRoleUnknown DTLSRole = iota + // DTLSRoleAuto defines the DTLS role is determined based on // the resolved ICE role: the ICE controlled role acts as the DTLS // client and the ICE controlling role acts as the DTLS server. - DTLSRoleAuto DTLSRole = iota + 1 + DTLSRoleAuto // DTLSRoleClient defines the DTLS client role. DTLSRoleClient @@ -51,7 +54,7 @@ func (r DTLSRole) String() string { case DTLSRoleServer: return "server" default: - return unknownStr + return ErrUnknownType.Error() } } diff --git a/vendor/github.com/pion/webrtc/v3/dtlstransport.go b/vendor/github.com/pion/webrtc/v4/dtlstransport.go similarity index 90% rename from vendor/github.com/pion/webrtc/v3/dtlstransport.go rename to vendor/github.com/pion/webrtc/v4/dtlstransport.go index beaa7b28c1..3e442923b5 100644 --- a/vendor/github.com/pion/webrtc/v3/dtlstransport.go +++ b/vendor/github.com/pion/webrtc/v4/dtlstransport.go @@ -19,15 +19,15 @@ import ( "sync/atomic" "time" - "github.com/pion/dtls/v2" - "github.com/pion/dtls/v2/pkg/crypto/fingerprint" + "github.com/pion/dtls/v3" + "github.com/pion/dtls/v3/pkg/crypto/fingerprint" "github.com/pion/interceptor" "github.com/pion/logging" "github.com/pion/rtcp" - "github.com/pion/srtp/v2" - "github.com/pion/webrtc/v3/internal/mux" - "github.com/pion/webrtc/v3/internal/util" - "github.com/pion/webrtc/v3/pkg/rtcerr" + "github.com/pion/srtp/v3" + "github.com/pion/webrtc/v4/internal/mux" + "github.com/pion/webrtc/v4/internal/util" + "github.com/pion/webrtc/v4/pkg/rtcerr" ) // DTLSTransport allows an application access to information about the DTLS @@ -44,7 +44,8 @@ type DTLSTransport struct { state DTLSTransportState srtpProtectionProfile srtp.ProtectionProfile - onStateChangeHandler func(DTLSTransportState) + onStateChangeHandler func(DTLSTransportState) + internalOnCloseHandler func() conn *dtls.Conn @@ -215,7 +216,12 @@ func (t *DTLSTransport) startSRTP() error { ) } - connState := t.conn.ConnectionState() + connState, ok := t.conn.ConnectionState() + if !ok { + // nolint + return fmt.Errorf("%w: Failed to get DTLS ConnectionState", errDtlsKeyExtractionFailed) + } + err := srtpConfig.ExtractSessionKeysFromDTLS(&connState, t.role() == DTLSRoleClient) if err != nil { // nolint @@ -283,7 +289,7 @@ func (t *DTLSTransport) role() DTLSRole { } // Start DTLS transport negotiation with the parameters of the remote DTLS transport -func (t *DTLSTransport) Start(remoteParameters DTLSParameters) error { +func (t *DTLSTransport) Start(remoteParameters DTLSParameters) error { //nolint: gocognit // Take lock and prepare connection, we must not hold the lock // when connecting prepareTransport := func() (DTLSRole, *dtls.Config, error) { @@ -322,11 +328,13 @@ func (t *DTLSTransport) Start(remoteParameters DTLSParameters) error { ClientAuth: dtls.RequireAnyClientCert, LoggerFactory: t.api.settingEngine.LoggerFactory, InsecureSkipVerify: !t.api.settingEngine.dtls.disableInsecureSkipVerify, + CustomCipherSuites: t.api.settingEngine.dtls.customCipherSuites, }, nil } var dtlsConn *dtls.Conn dtlsEndpoint := t.iceTransport.newEndpoint(mux.MatchDTLS) + dtlsEndpoint.SetOnClose(t.internalOnCloseHandler) role, dtlsConfig, err := prepareTransport() if err != nil { return err @@ -343,18 +351,29 @@ func (t *DTLSTransport) Start(remoteParameters DTLSParameters) error { dtlsConfig.FlightInterval = t.api.settingEngine.dtls.retransmissionInterval dtlsConfig.InsecureSkipVerifyHello = t.api.settingEngine.dtls.insecureSkipHelloVerify dtlsConfig.EllipticCurves = t.api.settingEngine.dtls.ellipticCurves - dtlsConfig.ConnectContextMaker = t.api.settingEngine.dtls.connectContextMaker dtlsConfig.ExtendedMasterSecret = t.api.settingEngine.dtls.extendedMasterSecret dtlsConfig.ClientCAs = t.api.settingEngine.dtls.clientCAs dtlsConfig.RootCAs = t.api.settingEngine.dtls.rootCAs dtlsConfig.KeyLogWriter = t.api.settingEngine.dtls.keyLogWriter + dtlsConfig.ClientHelloMessageHook = t.api.settingEngine.dtls.clientHelloMessageHook + dtlsConfig.ServerHelloMessageHook = t.api.settingEngine.dtls.serverHelloMessageHook + dtlsConfig.CertificateRequestMessageHook = t.api.settingEngine.dtls.certificateRequestMessageHook // Connect as DTLS Client/Server, function is blocking and we // must not hold the DTLSTransport lock if role == DTLSRoleClient { - dtlsConn, err = dtls.Client(dtlsEndpoint, dtlsConfig) + dtlsConn, err = dtls.Client(dtlsEndpoint, dtlsEndpoint.RemoteAddr(), dtlsConfig) } else { - dtlsConn, err = dtls.Server(dtlsEndpoint, dtlsConfig) + dtlsConn, err = dtls.Server(dtlsEndpoint, dtlsEndpoint.RemoteAddr(), dtlsConfig) + } + + if err == nil { + if t.api.settingEngine.dtls.connectContextMaker != nil { + handshakeCtx, _ := t.api.settingEngine.dtls.connectContextMaker() + err = dtlsConn.HandshakeContext(handshakeCtx) + } else { + err = dtlsConn.Handshake() + } } // Re-take the lock, nothing beyond here is blocking @@ -387,12 +406,17 @@ func (t *DTLSTransport) Start(remoteParameters DTLSParameters) error { } // Check the fingerprint if a certificate was exchanged - remoteCerts := dtlsConn.ConnectionState().PeerCertificates - if len(remoteCerts) == 0 { + connectionState, ok := dtlsConn.ConnectionState() + if !ok { + t.onStateChange(DTLSTransportStateFailed) + return errNoRemoteCertificate + } + + if len(connectionState.PeerCertificates) == 0 { t.onStateChange(DTLSTransportStateFailed) return errNoRemoteCertificate } - t.remoteCertificate = remoteCerts[0] + t.remoteCertificate = connectionState.PeerCertificates[0] if !t.api.settingEngine.disableCertificateFingerprintVerification { parsedRemoteCert, err := x509.ParseCertificate(t.remoteCertificate) diff --git a/vendor/github.com/pion/webrtc/v3/dtlstransport_js.go b/vendor/github.com/pion/webrtc/v4/dtlstransport_js.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/dtlstransport_js.go rename to vendor/github.com/pion/webrtc/v4/dtlstransport_js.go diff --git a/vendor/github.com/pion/webrtc/v3/dtlstransportstate.go b/vendor/github.com/pion/webrtc/v4/dtlstransportstate.go similarity index 93% rename from vendor/github.com/pion/webrtc/v3/dtlstransportstate.go rename to vendor/github.com/pion/webrtc/v4/dtlstransportstate.go index 573dd4bf03..c938ae2c0f 100644 --- a/vendor/github.com/pion/webrtc/v3/dtlstransportstate.go +++ b/vendor/github.com/pion/webrtc/v4/dtlstransportstate.go @@ -7,9 +7,12 @@ package webrtc type DTLSTransportState int const ( + // DTLSTransportStateUnknown is the enum's zero-value + DTLSTransportStateUnknown DTLSTransportState = iota + // DTLSTransportStateNew indicates that DTLS has not started negotiating // yet. - DTLSTransportStateNew DTLSTransportState = iota + 1 + DTLSTransportStateNew // DTLSTransportStateConnecting indicates that DTLS is in the process of // negotiating a secure connection and verifying the remote fingerprint. @@ -52,7 +55,7 @@ func newDTLSTransportState(raw string) DTLSTransportState { case dtlsTransportStateFailedStr: return DTLSTransportStateFailed default: - return DTLSTransportState(Unknown) + return DTLSTransportStateUnknown } } diff --git a/vendor/github.com/pion/webrtc/v3/errors.go b/vendor/github.com/pion/webrtc/v4/errors.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/errors.go rename to vendor/github.com/pion/webrtc/v4/errors.go diff --git a/vendor/github.com/pion/webrtc/v3/gathering_complete_promise.go b/vendor/github.com/pion/webrtc/v4/gathering_complete_promise.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/gathering_complete_promise.go rename to vendor/github.com/pion/webrtc/v4/gathering_complete_promise.go diff --git a/vendor/github.com/pion/webrtc/v3/ice_go.go b/vendor/github.com/pion/webrtc/v4/ice_go.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/ice_go.go rename to vendor/github.com/pion/webrtc/v4/ice_go.go diff --git a/vendor/github.com/pion/webrtc/v3/icecandidate.go b/vendor/github.com/pion/webrtc/v4/icecandidate.go similarity index 99% rename from vendor/github.com/pion/webrtc/v3/icecandidate.go rename to vendor/github.com/pion/webrtc/v4/icecandidate.go index fa0b68093a..c36d520543 100644 --- a/vendor/github.com/pion/webrtc/v3/icecandidate.go +++ b/vendor/github.com/pion/webrtc/v4/icecandidate.go @@ -6,7 +6,7 @@ package webrtc import ( "fmt" - "github.com/pion/ice/v2" + "github.com/pion/ice/v4" ) // ICECandidate represents a ice candidate diff --git a/vendor/github.com/pion/webrtc/v3/icecandidateinit.go b/vendor/github.com/pion/webrtc/v4/icecandidateinit.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/icecandidateinit.go rename to vendor/github.com/pion/webrtc/v4/icecandidateinit.go diff --git a/vendor/github.com/pion/webrtc/v3/icecandidatepair.go b/vendor/github.com/pion/webrtc/v4/icecandidatepair.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/icecandidatepair.go rename to vendor/github.com/pion/webrtc/v4/icecandidatepair.go diff --git a/vendor/github.com/pion/webrtc/v3/icecandidatetype.go b/vendor/github.com/pion/webrtc/v4/icecandidatetype.go similarity index 88% rename from vendor/github.com/pion/webrtc/v3/icecandidatetype.go rename to vendor/github.com/pion/webrtc/v4/icecandidatetype.go index 5bef825b30..27d7a1422f 100644 --- a/vendor/github.com/pion/webrtc/v3/icecandidatetype.go +++ b/vendor/github.com/pion/webrtc/v4/icecandidatetype.go @@ -6,21 +6,24 @@ package webrtc import ( "fmt" - "github.com/pion/ice/v2" + "github.com/pion/ice/v4" ) // ICECandidateType represents the type of the ICE candidate used. type ICECandidateType int const ( + // ICECandidateTypeUnknown is the enum's zero-value + ICECandidateTypeUnknown ICECandidateType = iota + // ICECandidateTypeHost indicates that the candidate is of Host type as // described in https://tools.ietf.org/html/rfc8445#section-5.1.1.1. A // candidate obtained by binding to a specific port from an IP address on // the host. This includes IP addresses on physical interfaces and logical // ones, such as ones obtained through VPNs. - ICECandidateTypeHost ICECandidateType = iota + 1 + ICECandidateTypeHost - // ICECandidateTypeSrflx indicates the the candidate is of Server + // ICECandidateTypeSrflx indicates the candidate is of Server // Reflexive type as described // https://tools.ietf.org/html/rfc8445#section-5.1.1.2. A candidate type // whose IP address and port are a binding allocated by a NAT for an ICE @@ -34,7 +37,7 @@ const ( // NAT to its peer. ICECandidateTypePrflx - // ICECandidateTypeRelay indicates the the candidate is of Relay type as + // ICECandidateTypeRelay indicates the candidate is of Relay type as // described in https://tools.ietf.org/html/rfc8445#section-5.1.1.2. A // candidate type obtained from a relay server, such as a TURN server. ICECandidateTypeRelay @@ -60,7 +63,7 @@ func NewICECandidateType(raw string) (ICECandidateType, error) { case iceCandidateTypeRelayStr: return ICECandidateTypeRelay, nil default: - return ICECandidateType(Unknown), fmt.Errorf("%w: %s", errICECandidateTypeUnknown, raw) + return ICECandidateTypeUnknown, fmt.Errorf("%w: %s", errICECandidateTypeUnknown, raw) } } @@ -92,7 +95,7 @@ func getCandidateType(candidateType ice.CandidateType) (ICECandidateType, error) default: // NOTE: this should never happen[tm] err := fmt.Errorf("%w: %s", errICEInvalidConvertCandidateType, candidateType.String()) - return ICECandidateType(Unknown), err + return ICECandidateTypeUnknown, err } } diff --git a/vendor/github.com/pion/webrtc/v3/icecomponent.go b/vendor/github.com/pion/webrtc/v4/icecomponent.go similarity index 90% rename from vendor/github.com/pion/webrtc/v3/icecomponent.go rename to vendor/github.com/pion/webrtc/v4/icecomponent.go index c65a893dcd..ae8f230fbf 100644 --- a/vendor/github.com/pion/webrtc/v3/icecomponent.go +++ b/vendor/github.com/pion/webrtc/v4/icecomponent.go @@ -8,12 +8,15 @@ package webrtc type ICEComponent int const ( + // ICEComponentUnknown is the enum's zero-value + ICEComponentUnknown ICEComponent = iota + // ICEComponentRTP indicates that the ICE Transport is used for RTP (or // RTCP multiplexing), as defined in // https://tools.ietf.org/html/rfc5245#section-4.1.1.1. Protocols // multiplexed with RTP (e.g. data channel) share its component ID. This // represents the component-id value 1 when encoded in candidate-attribute. - ICEComponentRTP ICEComponent = iota + 1 + ICEComponentRTP // ICEComponentRTCP indicates that the ICE Transport is used for RTCP as // defined by https://tools.ietf.org/html/rfc5245#section-4.1.1.1. This @@ -34,7 +37,7 @@ func newICEComponent(raw string) ICEComponent { case iceComponentRTCPStr: return ICEComponentRTCP default: - return ICEComponent(Unknown) + return ICEComponentUnknown } } diff --git a/vendor/github.com/pion/webrtc/v3/iceconnectionstate.go b/vendor/github.com/pion/webrtc/v4/iceconnectionstate.go similarity index 95% rename from vendor/github.com/pion/webrtc/v3/iceconnectionstate.go rename to vendor/github.com/pion/webrtc/v4/iceconnectionstate.go index e52e1328ae..4b7deb802f 100644 --- a/vendor/github.com/pion/webrtc/v3/iceconnectionstate.go +++ b/vendor/github.com/pion/webrtc/v4/iceconnectionstate.go @@ -7,11 +7,14 @@ package webrtc type ICEConnectionState int const ( + // ICEConnectionStateUnknown is the enum's zero-value + ICEConnectionStateUnknown ICEConnectionState = iota + // ICEConnectionStateNew indicates that any of the ICETransports are // in the "new" state and none of them are in the "checking", "disconnected" // or "failed" state, or all ICETransports are in the "closed" state, or // there are no transports. - ICEConnectionStateNew ICEConnectionState = iota + 1 + ICEConnectionStateNew // ICEConnectionStateChecking indicates that any of the ICETransports // are in the "checking" state and none of them are in the "disconnected" @@ -71,7 +74,7 @@ func NewICEConnectionState(raw string) ICEConnectionState { case iceConnectionStateClosedStr: return ICEConnectionStateClosed default: - return ICEConnectionState(Unknown) + return ICEConnectionStateUnknown } } diff --git a/vendor/github.com/pion/webrtc/v3/icecredentialtype.go b/vendor/github.com/pion/webrtc/v4/icecredentialtype.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/icecredentialtype.go rename to vendor/github.com/pion/webrtc/v4/icecredentialtype.go diff --git a/vendor/github.com/pion/webrtc/v3/icegatherer.go b/vendor/github.com/pion/webrtc/v4/icegatherer.go similarity index 98% rename from vendor/github.com/pion/webrtc/v3/icegatherer.go rename to vendor/github.com/pion/webrtc/v4/icegatherer.go index b772f451d5..b15c72b545 100644 --- a/vendor/github.com/pion/webrtc/v3/icegatherer.go +++ b/vendor/github.com/pion/webrtc/v4/icegatherer.go @@ -11,9 +11,9 @@ import ( "sync" "sync/atomic" - "github.com/pion/ice/v2" + "github.com/pion/ice/v4" "github.com/pion/logging" - "github.com/pion/stun" + "github.com/pion/stun/v3" ) // ICEGatherer gathers local host, server reflexive and relay @@ -108,6 +108,7 @@ func (g *ICEGatherer) createAgent() error { SrflxAcceptanceMinWait: g.api.settingEngine.timeout.ICESrflxAcceptanceMinWait, PrflxAcceptanceMinWait: g.api.settingEngine.timeout.ICEPrflxAcceptanceMinWait, RelayAcceptanceMinWait: g.api.settingEngine.timeout.ICERelayAcceptanceMinWait, + STUNGatherTimeout: g.api.settingEngine.timeout.ICESTUNGatherTimeout, InterfaceFilter: g.api.settingEngine.candidates.InterfaceFilter, IPFilter: g.api.settingEngine.candidates.IPFilter, NAT1To1IPs: g.api.settingEngine.candidates.NAT1To1IPs, @@ -122,6 +123,7 @@ func (g *ICEGatherer) createAgent() error { UDPMux: g.api.settingEngine.iceUDPMux, ProxyDialer: g.api.settingEngine.iceProxyDialer, DisableActiveTCP: g.api.settingEngine.iceDisableActiveTCP, + MaxBindingRequests: g.api.settingEngine.iceMaxBindingRequests, BindingRequestHandler: g.api.settingEngine.iceBindingRequestHandler, } diff --git a/vendor/github.com/pion/webrtc/v3/icegathererstate.go b/vendor/github.com/pion/webrtc/v4/icegathererstate.go similarity index 89% rename from vendor/github.com/pion/webrtc/v3/icegathererstate.go rename to vendor/github.com/pion/webrtc/v4/icegathererstate.go index b90acd33ee..b78df5fc5f 100644 --- a/vendor/github.com/pion/webrtc/v3/icegathererstate.go +++ b/vendor/github.com/pion/webrtc/v4/icegathererstate.go @@ -11,9 +11,12 @@ import ( type ICEGathererState uint32 const ( + // ICEGathererStateUnknown is the enum's zero-value + ICEGathererStateUnknown ICEGathererState = iota + // ICEGathererStateNew indicates object has been created but // gather() has not been called. - ICEGathererStateNew ICEGathererState = iota + 1 + ICEGathererStateNew // ICEGathererStateGathering indicates gather() has been called, // and the ICEGatherer is in the process of gathering candidates. @@ -38,7 +41,7 @@ func (s ICEGathererState) String() string { case ICEGathererStateClosed: return "closed" default: - return unknownStr + return ErrUnknownType.Error() } } diff --git a/vendor/github.com/pion/webrtc/v3/icegatheringstate.go b/vendor/github.com/pion/webrtc/v4/icegatheringstate.go similarity index 90% rename from vendor/github.com/pion/webrtc/v3/icegatheringstate.go rename to vendor/github.com/pion/webrtc/v4/icegatheringstate.go index 1925dddbfe..13ea2f73d4 100644 --- a/vendor/github.com/pion/webrtc/v3/icegatheringstate.go +++ b/vendor/github.com/pion/webrtc/v4/icegatheringstate.go @@ -7,10 +7,13 @@ package webrtc type ICEGatheringState int const ( + // ICEGatheringStateUnknown is the enum's zero-value + ICEGatheringStateUnknown ICEGatheringState = iota + // ICEGatheringStateNew indicates that any of the ICETransports are // in the "new" gathering state and none of the transports are in the // "gathering" state, or there are no transports. - ICEGatheringStateNew ICEGatheringState = iota + 1 + ICEGatheringStateNew // ICEGatheringStateGathering indicates that any of the ICETransports // are in the "gathering" state. @@ -38,7 +41,7 @@ func NewICEGatheringState(raw string) ICEGatheringState { case iceGatheringStateCompleteStr: return ICEGatheringStateComplete default: - return ICEGatheringState(Unknown) + return ICEGatheringStateUnknown } } diff --git a/vendor/github.com/pion/webrtc/v3/icegatheroptions.go b/vendor/github.com/pion/webrtc/v4/icegatheroptions.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/icegatheroptions.go rename to vendor/github.com/pion/webrtc/v4/icegatheroptions.go diff --git a/vendor/github.com/pion/webrtc/v3/icemux.go b/vendor/github.com/pion/webrtc/v4/icemux.go similarity index 96% rename from vendor/github.com/pion/webrtc/v3/icemux.go rename to vendor/github.com/pion/webrtc/v4/icemux.go index 1bae313109..4f7ecb3f3d 100644 --- a/vendor/github.com/pion/webrtc/v3/icemux.go +++ b/vendor/github.com/pion/webrtc/v4/icemux.go @@ -6,7 +6,7 @@ package webrtc import ( "net" - "github.com/pion/ice/v2" + "github.com/pion/ice/v4" "github.com/pion/logging" ) diff --git a/vendor/github.com/pion/webrtc/v3/iceparameters.go b/vendor/github.com/pion/webrtc/v4/iceparameters.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/iceparameters.go rename to vendor/github.com/pion/webrtc/v4/iceparameters.go diff --git a/vendor/github.com/pion/webrtc/v3/iceprotocol.go b/vendor/github.com/pion/webrtc/v4/iceprotocol.go similarity index 84% rename from vendor/github.com/pion/webrtc/v3/iceprotocol.go rename to vendor/github.com/pion/webrtc/v4/iceprotocol.go index 3582b68301..67254f7d2f 100644 --- a/vendor/github.com/pion/webrtc/v3/iceprotocol.go +++ b/vendor/github.com/pion/webrtc/v4/iceprotocol.go @@ -13,8 +13,11 @@ import ( type ICEProtocol int const ( + // ICEProtocolUnknown is the enum's zero-value + ICEProtocolUnknown ICEProtocol = iota + // ICEProtocolUDP indicates the URL uses a UDP transport. - ICEProtocolUDP ICEProtocol = iota + 1 + ICEProtocolUDP // ICEProtocolTCP indicates the URL uses a TCP transport. ICEProtocolTCP @@ -34,7 +37,7 @@ func NewICEProtocol(raw string) (ICEProtocol, error) { case strings.EqualFold(iceProtocolTCPStr, raw): return ICEProtocolTCP, nil default: - return ICEProtocol(Unknown), fmt.Errorf("%w: %s", errICEProtocolUnknown, raw) + return ICEProtocolUnknown, fmt.Errorf("%w: %s", errICEProtocolUnknown, raw) } } diff --git a/vendor/github.com/pion/webrtc/v3/icerole.go b/vendor/github.com/pion/webrtc/v4/icerole.go similarity index 92% rename from vendor/github.com/pion/webrtc/v3/icerole.go rename to vendor/github.com/pion/webrtc/v4/icerole.go index a46b45590f..dce6336e9f 100644 --- a/vendor/github.com/pion/webrtc/v3/icerole.go +++ b/vendor/github.com/pion/webrtc/v4/icerole.go @@ -8,11 +8,14 @@ package webrtc type ICERole int const ( + // ICERoleUnknown is the enum's zero-value + ICERoleUnknown ICERole = iota + // ICERoleControlling indicates that the ICE agent that is responsible // for selecting the final choice of candidate pairs and signaling them // through STUN and an updated offer, if needed. In any session, one agent // is always controlling. The other is the controlled agent. - ICERoleControlling ICERole = iota + 1 + ICERoleControlling // ICERoleControlled indicates that an ICE agent that waits for the // controlling agent to select the final choice of candidate pairs. @@ -32,7 +35,7 @@ func newICERole(raw string) ICERole { case iceRoleControlledStr: return ICERoleControlled default: - return ICERole(Unknown) + return ICERoleUnknown } } diff --git a/vendor/github.com/pion/webrtc/v3/iceserver.go b/vendor/github.com/pion/webrtc/v4/iceserver.go similarity index 98% rename from vendor/github.com/pion/webrtc/v3/iceserver.go rename to vendor/github.com/pion/webrtc/v4/iceserver.go index 35d231fd57..a28e727eb4 100644 --- a/vendor/github.com/pion/webrtc/v3/iceserver.go +++ b/vendor/github.com/pion/webrtc/v4/iceserver.go @@ -9,8 +9,8 @@ package webrtc import ( "encoding/json" - "github.com/pion/stun" - "github.com/pion/webrtc/v3/pkg/rtcerr" + "github.com/pion/stun/v3" + "github.com/pion/webrtc/v4/pkg/rtcerr" ) // ICEServer describes a single STUN and TURN server that can be used by diff --git a/vendor/github.com/pion/webrtc/v3/iceserver_js.go b/vendor/github.com/pion/webrtc/v4/iceserver_js.go similarity index 97% rename from vendor/github.com/pion/webrtc/v3/iceserver_js.go rename to vendor/github.com/pion/webrtc/v4/iceserver_js.go index e4061fa5f4..2f293dde0f 100644 --- a/vendor/github.com/pion/webrtc/v3/iceserver_js.go +++ b/vendor/github.com/pion/webrtc/v4/iceserver_js.go @@ -9,7 +9,7 @@ package webrtc import ( "errors" - "github.com/pion/ice/v2" + "github.com/pion/ice/v4" ) // ICEServer describes a single STUN and TURN server that can be used by diff --git a/vendor/github.com/pion/webrtc/v3/icetransport.go b/vendor/github.com/pion/webrtc/v4/icetransport.go similarity index 98% rename from vendor/github.com/pion/webrtc/v3/icetransport.go rename to vendor/github.com/pion/webrtc/v4/icetransport.go index 6724a94280..a86d4f94f1 100644 --- a/vendor/github.com/pion/webrtc/v3/icetransport.go +++ b/vendor/github.com/pion/webrtc/v4/icetransport.go @@ -13,10 +13,10 @@ import ( "sync/atomic" "time" - "github.com/pion/ice/v2" + "github.com/pion/ice/v4" "github.com/pion/logging" - "github.com/pion/webrtc/v3/internal/mux" - "github.com/pion/webrtc/v3/internal/util" + "github.com/pion/webrtc/v4/internal/mux" + "github.com/pion/webrtc/v4/internal/util" ) // ICETransport allows an application access to information about the ICE diff --git a/vendor/github.com/pion/webrtc/v3/icetransport_js.go b/vendor/github.com/pion/webrtc/v4/icetransport_js.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/icetransport_js.go rename to vendor/github.com/pion/webrtc/v4/icetransport_js.go diff --git a/vendor/github.com/pion/webrtc/v3/icetransportpolicy.go b/vendor/github.com/pion/webrtc/v4/icetransportpolicy.go similarity index 96% rename from vendor/github.com/pion/webrtc/v3/icetransportpolicy.go rename to vendor/github.com/pion/webrtc/v4/icetransportpolicy.go index a2629fdab4..d9a41637a0 100644 --- a/vendor/github.com/pion/webrtc/v3/icetransportpolicy.go +++ b/vendor/github.com/pion/webrtc/v4/icetransportpolicy.go @@ -34,10 +34,8 @@ func NewICETransportPolicy(raw string) ICETransportPolicy { switch raw { case iceTransportPolicyRelayStr: return ICETransportPolicyRelay - case iceTransportPolicyAllStr: - return ICETransportPolicyAll default: - return ICETransportPolicy(Unknown) + return ICETransportPolicyAll } } diff --git a/vendor/github.com/pion/webrtc/v3/icetransportstate.go b/vendor/github.com/pion/webrtc/v4/icetransportstate.go similarity index 64% rename from vendor/github.com/pion/webrtc/v3/icetransportstate.go rename to vendor/github.com/pion/webrtc/v4/icetransportstate.go index 4edbf0f475..645c5c7746 100644 --- a/vendor/github.com/pion/webrtc/v3/icetransportstate.go +++ b/vendor/github.com/pion/webrtc/v4/icetransportstate.go @@ -3,15 +3,18 @@ package webrtc -import "github.com/pion/ice/v2" +import "github.com/pion/ice/v4" // ICETransportState represents the current state of the ICE transport. type ICETransportState int const ( + // ICETransportStateUnknown is the enum's zero-value + ICETransportStateUnknown ICETransportState = iota + // ICETransportStateNew indicates the ICETransport is waiting // for remote candidates to be supplied. - ICETransportStateNew = iota + 1 + ICETransportStateNew // ICETransportStateChecking indicates the ICETransport has // received at least one remote candidate, and a local and remote @@ -46,24 +49,55 @@ const ( ICETransportStateClosed ) +const ( + iceTransportStateNewStr = "new" + iceTransportStateCheckingStr = "checking" + iceTransportStateConnectedStr = "connected" + iceTransportStateCompletedStr = "completed" + iceTransportStateFailedStr = "failed" + iceTransportStateDisconnectedStr = "disconnected" + iceTransportStateClosedStr = "closed" +) + +func newICETransportState(raw string) ICETransportState { + switch raw { + case iceTransportStateNewStr: + return ICETransportStateNew + case iceTransportStateCheckingStr: + return ICETransportStateChecking + case iceTransportStateConnectedStr: + return ICETransportStateConnected + case iceTransportStateCompletedStr: + return ICETransportStateCompleted + case iceTransportStateFailedStr: + return ICETransportStateFailed + case iceTransportStateDisconnectedStr: + return ICETransportStateDisconnected + case iceTransportStateClosedStr: + return ICETransportStateClosed + default: + return ICETransportStateUnknown + } +} + func (c ICETransportState) String() string { switch c { case ICETransportStateNew: - return "new" + return iceTransportStateNewStr case ICETransportStateChecking: - return "checking" + return iceTransportStateCheckingStr case ICETransportStateConnected: - return "connected" + return iceTransportStateConnectedStr case ICETransportStateCompleted: - return "completed" + return iceTransportStateCompletedStr case ICETransportStateFailed: - return "failed" + return iceTransportStateFailedStr case ICETransportStateDisconnected: - return "disconnected" + return iceTransportStateDisconnectedStr case ICETransportStateClosed: - return "closed" + return iceTransportStateClosedStr default: - return unknownStr + return ErrUnknownType.Error() } } @@ -84,7 +118,7 @@ func newICETransportStateFromICE(i ice.ConnectionState) ICETransportState { case ice.ConnectionStateClosed: return ICETransportStateClosed default: - return ICETransportState(Unknown) + return ICETransportStateUnknown } } @@ -105,6 +139,17 @@ func (c ICETransportState) toICE() ice.ConnectionState { case ICETransportStateClosed: return ice.ConnectionStateClosed default: - return ice.ConnectionState(Unknown) + return ice.ConnectionStateUnknown } } + +// MarshalText implements encoding.TextMarshaler +func (c ICETransportState) MarshalText() ([]byte, error) { + return []byte(c.String()), nil +} + +// UnmarshalText implements encoding.TextUnmarshaler +func (c *ICETransportState) UnmarshalText(b []byte) error { + *c = newICETransportState(string(b)) + return nil +} diff --git a/vendor/github.com/pion/webrtc/v3/interceptor.go b/vendor/github.com/pion/webrtc/v4/interceptor.go similarity index 74% rename from vendor/github.com/pion/webrtc/v3/interceptor.go rename to vendor/github.com/pion/webrtc/v4/interceptor.go index 7a5b4a7240..59c97b471a 100644 --- a/vendor/github.com/pion/webrtc/v3/interceptor.go +++ b/vendor/github.com/pion/webrtc/v4/interceptor.go @@ -12,6 +12,7 @@ import ( "github.com/pion/interceptor" "github.com/pion/interceptor/pkg/nack" "github.com/pion/interceptor/pkg/report" + "github.com/pion/interceptor/pkg/rfc8888" "github.com/pion/interceptor/pkg/twcc" "github.com/pion/rtp" "github.com/pion/sdp/v3" @@ -29,6 +30,10 @@ func RegisterDefaultInterceptors(mediaEngine *MediaEngine, interceptorRegistry * return err } + if err := ConfigureSimulcastExtensionHeaders(mediaEngine); err != nil { + return err + } + return ConfigureTWCCSender(mediaEngine, interceptorRegistry) } @@ -109,6 +114,19 @@ func ConfigureTWCCSender(mediaEngine *MediaEngine, interceptorRegistry *intercep return nil } +// ConfigureCongestionControlFeedback registers congestion control feedback as +// defined in RFC 8888 (https://datatracker.ietf.org/doc/rfc8888/) +func ConfigureCongestionControlFeedback(mediaEngine *MediaEngine, interceptorRegistry *interceptor.Registry) error { + mediaEngine.RegisterFeedback(RTCPFeedback{Type: TypeRTCPFBACK, Parameter: "ccfb"}, RTPCodecTypeVideo) + mediaEngine.RegisterFeedback(RTCPFeedback{Type: TypeRTCPFBACK, Parameter: "ccfb"}, RTPCodecTypeAudio) + generator, err := rfc8888.NewSenderInterceptor() + if err != nil { + return err + } + interceptorRegistry.Add(generator) + return nil +} + // ConfigureSimulcastExtensionHeaders enables the RTP Extension Headers needed for Simulcast func ConfigureSimulcastExtensionHeaders(mediaEngine *MediaEngine) error { if err := mediaEngine.RegisterHeaderExtension(RTPHeaderExtensionCapability{URI: sdp.SDESMidURI}, RTPCodecTypeVideo); err != nil { @@ -141,7 +159,8 @@ func (i *interceptorToTrackLocalWriter) Write(b []byte) (int, error) { return i.WriteRTP(&packet.Header, packet.Payload) } -func createStreamInfo(id string, ssrc SSRC, payloadType PayloadType, codec RTPCodecCapability, webrtcHeaderExtensions []RTPHeaderExtensionParameter) *interceptor.StreamInfo { +// nolint: unparam +func createStreamInfo(id string, ssrc, ssrcRTX, ssrcFEC SSRC, payloadType, payloadTypeRTX, payloadTypeFEC PayloadType, codec RTPCodecCapability, webrtcHeaderExtensions []RTPHeaderExtensionParameter) *interceptor.StreamInfo { headerExtensions := make([]interceptor.RTPHeaderExtension, 0, len(webrtcHeaderExtensions)) for _, h := range webrtcHeaderExtensions { headerExtensions = append(headerExtensions, interceptor.RTPHeaderExtension{ID: h.ID, URI: h.URI}) @@ -153,15 +172,19 @@ func createStreamInfo(id string, ssrc SSRC, payloadType PayloadType, codec RTPCo } return &interceptor.StreamInfo{ - ID: id, - Attributes: interceptor.Attributes{}, - SSRC: uint32(ssrc), - PayloadType: uint8(payloadType), - RTPHeaderExtensions: headerExtensions, - MimeType: codec.MimeType, - ClockRate: codec.ClockRate, - Channels: codec.Channels, - SDPFmtpLine: codec.SDPFmtpLine, - RTCPFeedback: feedbacks, + ID: id, + Attributes: interceptor.Attributes{}, + SSRC: uint32(ssrc), + SSRCRetransmission: uint32(ssrcRTX), + SSRCForwardErrorCorrection: uint32(ssrcFEC), + PayloadType: uint8(payloadType), + PayloadTypeRetransmission: uint8(payloadTypeRTX), + PayloadTypeForwardErrorCorrection: uint8(payloadTypeFEC), + RTPHeaderExtensions: headerExtensions, + MimeType: codec.MimeType, + ClockRate: codec.ClockRate, + Channels: codec.Channels, + SDPFmtpLine: codec.SDPFmtpLine, + RTCPFeedback: feedbacks, } } diff --git a/vendor/github.com/pion/webrtc/v3/internal/fmtp/av1.go b/vendor/github.com/pion/webrtc/v4/internal/fmtp/av1.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/internal/fmtp/av1.go rename to vendor/github.com/pion/webrtc/v4/internal/fmtp/av1.go diff --git a/vendor/github.com/pion/webrtc/v3/internal/fmtp/fmtp.go b/vendor/github.com/pion/webrtc/v4/internal/fmtp/fmtp.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/internal/fmtp/fmtp.go rename to vendor/github.com/pion/webrtc/v4/internal/fmtp/fmtp.go diff --git a/vendor/github.com/pion/webrtc/v3/internal/fmtp/h264.go b/vendor/github.com/pion/webrtc/v4/internal/fmtp/h264.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/internal/fmtp/h264.go rename to vendor/github.com/pion/webrtc/v4/internal/fmtp/h264.go diff --git a/vendor/github.com/pion/webrtc/v3/internal/fmtp/vp9.go b/vendor/github.com/pion/webrtc/v4/internal/fmtp/vp9.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/internal/fmtp/vp9.go rename to vendor/github.com/pion/webrtc/v4/internal/fmtp/vp9.go diff --git a/vendor/github.com/pion/webrtc/v3/internal/mux/endpoint.go b/vendor/github.com/pion/webrtc/v4/internal/mux/endpoint.go similarity index 66% rename from vendor/github.com/pion/webrtc/v3/internal/mux/endpoint.go rename to vendor/github.com/pion/webrtc/v4/internal/mux/endpoint.go index 3f53d16c5d..2a3d03571f 100644 --- a/vendor/github.com/pion/webrtc/v3/internal/mux/endpoint.go +++ b/vendor/github.com/pion/webrtc/v4/internal/mux/endpoint.go @@ -9,20 +9,24 @@ import ( "net" "time" - "github.com/pion/ice/v2" - "github.com/pion/transport/v2/packetio" + "github.com/pion/ice/v4" + "github.com/pion/transport/v3/packetio" ) // Endpoint implements net.Conn. It is used to read muxed packets. type Endpoint struct { - mux *Mux - buffer *packetio.Buffer + mux *Mux + buffer *packetio.Buffer + onClose func() } // Close unregisters the endpoint from the Mux func (e *Endpoint) Close() (err error) { - err = e.close() - if err != nil { + if e.onClose != nil { + e.onClose() + } + + if err = e.close(); err != nil { return err } @@ -40,6 +44,13 @@ func (e *Endpoint) Read(p []byte) (int, error) { return e.buffer.Read(p) } +// ReadFrom reads a packet of len(p) bytes from the underlying conn +// that are matched by the associated MuxFunc +func (e *Endpoint) ReadFrom(p []byte) (int, net.Addr, error) { + i, err := e.Read(p) + return i, nil, err +} + // Write writes len(p) bytes to the underlying conn func (e *Endpoint) Write(p []byte) (int, error) { n, err := e.mux.nextConn.Write(p) @@ -52,6 +63,11 @@ func (e *Endpoint) Write(p []byte) (int, error) { return n, err } +// WriteTo writes len(p) bytes to the underlying conn +func (e *Endpoint) WriteTo(p []byte, _ net.Addr) (int, error) { + return e.Write(p) +} + // LocalAddr is a stub func (e *Endpoint) LocalAddr() net.Addr { return e.mux.nextConn.LocalAddr() @@ -76,3 +92,9 @@ func (e *Endpoint) SetReadDeadline(time.Time) error { func (e *Endpoint) SetWriteDeadline(time.Time) error { return nil } + +// SetOnClose is a user set callback that +// will be executed when `Close` is called +func (e *Endpoint) SetOnClose(onClose func()) { + e.onClose = onClose +} diff --git a/vendor/github.com/pion/webrtc/v3/internal/mux/mux.go b/vendor/github.com/pion/webrtc/v4/internal/mux/mux.go similarity index 66% rename from vendor/github.com/pion/webrtc/v3/internal/mux/mux.go rename to vendor/github.com/pion/webrtc/v4/internal/mux/mux.go index d57b9c3cf3..02e3acae93 100644 --- a/vendor/github.com/pion/webrtc/v3/internal/mux/mux.go +++ b/vendor/github.com/pion/webrtc/v4/internal/mux/mux.go @@ -10,13 +10,18 @@ import ( "net" "sync" - "github.com/pion/ice/v2" + "github.com/pion/ice/v4" "github.com/pion/logging" - "github.com/pion/transport/v2/packetio" + "github.com/pion/transport/v3/packetio" ) -// The maximum amount of data that can be buffered before returning errors. -const maxBufferSize = 1000 * 1000 // 1MB +const ( + // The maximum amount of data that can be buffered before returning errors. + maxBufferSize = 1000 * 1000 // 1MB + + // How many total pending packets can be cached + maxPendingPackets = 15 +) // Config collects the arguments to mux.Mux construction into // a single structure @@ -28,13 +33,16 @@ type Config struct { // Mux allows multiplexing type Mux struct { - lock sync.RWMutex nextConn net.Conn - endpoints map[*Endpoint]MatchFunc bufferSize int - closedCh chan struct{} + lock sync.Mutex + endpoints map[*Endpoint]MatchFunc + isClosed bool + + pendingPackets [][]byte - log logging.LeveledLogger + closedCh chan struct{} + log logging.LeveledLogger } // NewMux creates a new Mux @@ -66,6 +74,8 @@ func (m *Mux) NewEndpoint(f MatchFunc) *Endpoint { m.endpoints[e] = f m.lock.Unlock() + go m.handlePendingPackets(e, f) + return e } @@ -87,6 +97,7 @@ func (m *Mux) Close() error { delete(m.endpoints, e) } + m.isClosed = true m.lock.Unlock() err := m.nextConn.Close() @@ -131,6 +142,11 @@ func (m *Mux) readLoop() { } func (m *Mux) dispatch(buf []byte) error { + if len(buf) == 0 { + m.log.Warnf("Warning: mux: unable to dispatch zero length packet") + return nil + } + var endpoint *Endpoint m.lock.Lock() @@ -140,17 +156,21 @@ func (m *Mux) dispatch(buf []byte) error { break } } - m.lock.Unlock() - if endpoint == nil { - if len(buf) > 0 { - m.log.Warnf("Warning: mux: no endpoint for packet starting with %d", buf[0]) - } else { - m.log.Warnf("Warning: mux: no endpoint for zero length packet") + defer m.lock.Unlock() + + if !m.isClosed { + if len(m.pendingPackets) >= maxPendingPackets { + m.log.Warnf("Warning: mux: no endpoint for packet starting with %d, not adding to queue size(%d)", buf[0], len(m.pendingPackets)) + } else { + m.log.Warnf("Warning: mux: no endpoint for packet starting with %d, adding to queue size(%d)", buf[0], len(m.pendingPackets)) + m.pendingPackets = append(m.pendingPackets, append([]byte{}, buf...)) + } } return nil } + m.lock.Unlock() _, err := endpoint.buffer.Write(buf) // Expected when bytes are received faster than the endpoint can process them (#2152, #2180) @@ -161,3 +181,20 @@ func (m *Mux) dispatch(buf []byte) error { return err } + +func (m *Mux) handlePendingPackets(endpoint *Endpoint, matchFunc MatchFunc) { + m.lock.Lock() + defer m.lock.Unlock() + + pendingPackets := make([][]byte, len(m.pendingPackets)) + for _, buf := range m.pendingPackets { + if matchFunc(buf) { + if _, err := endpoint.buffer.Write(buf); err != nil { + m.log.Warnf("Warning: mux: error writing packet to endpoint from pending queue: %s", err) + } + } else { + pendingPackets = append(pendingPackets, buf) + } + } + m.pendingPackets = pendingPackets +} diff --git a/vendor/github.com/pion/webrtc/v3/internal/mux/muxfunc.go b/vendor/github.com/pion/webrtc/v4/internal/mux/muxfunc.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/internal/mux/muxfunc.go rename to vendor/github.com/pion/webrtc/v4/internal/mux/muxfunc.go diff --git a/vendor/github.com/pion/webrtc/v3/internal/util/util.go b/vendor/github.com/pion/webrtc/v4/internal/util/util.go similarity index 91% rename from vendor/github.com/pion/webrtc/v3/internal/util/util.go rename to vendor/github.com/pion/webrtc/v4/internal/util/util.go index 3f43c123e5..966a6230a6 100644 --- a/vendor/github.com/pion/webrtc/v3/internal/util/util.go +++ b/vendor/github.com/pion/webrtc/v4/internal/util/util.go @@ -18,12 +18,12 @@ const ( // Use global random generator to properly seed by crypto grade random. var globalMathRandomGenerator = randutil.NewMathRandomGenerator() // nolint:gochecknoglobals -// MathRandAlpha generates a mathmatical random alphabet sequence of the requested length. +// MathRandAlpha generates a mathematical random alphabet sequence of the requested length. func MathRandAlpha(n int) string { return globalMathRandomGenerator.GenerateString(n, runesAlpha) } -// RandUint32 generates a mathmatical random uint32. +// RandUint32 generates a mathematical random uint32. func RandUint32() uint32 { return globalMathRandomGenerator.Uint32() } diff --git a/vendor/github.com/pion/webrtc/v3/js_utils.go b/vendor/github.com/pion/webrtc/v4/js_utils.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/js_utils.go rename to vendor/github.com/pion/webrtc/v4/js_utils.go diff --git a/vendor/github.com/pion/webrtc/v3/mediaengine.go b/vendor/github.com/pion/webrtc/v4/mediaengine.go similarity index 92% rename from vendor/github.com/pion/webrtc/v3/mediaengine.go rename to vendor/github.com/pion/webrtc/v4/mediaengine.go index a7cfa88263..a386d78a7f 100644 --- a/vendor/github.com/pion/webrtc/v3/mediaengine.go +++ b/vendor/github.com/pion/webrtc/v4/mediaengine.go @@ -16,7 +16,7 @@ import ( "github.com/pion/rtp" "github.com/pion/rtp/codecs" "github.com/pion/sdp/v3" - "github.com/pion/webrtc/v3/internal/fmtp" + "github.com/pion/webrtc/v4/internal/fmtp" ) const ( @@ -47,6 +47,12 @@ const ( // MimeTypePCMA PCMA MIME type // Note: Matching should be case insensitive. MimeTypePCMA = "audio/PCMA" + // MimeTypeRTX RTX MIME type + // Note: Matching should be case insensitive. + MimeTypeRTX = "video/rtx" + // MimeTypeFlexFEC FEC MIME Type + // Note: Matching should be case insensitive. + MimeTypeFlexFEC = "video/flexfec" ) type mediaEngineHeaderExtension struct { @@ -83,15 +89,15 @@ func (m *MediaEngine) RegisterDefaultCodecs() error { }, { RTPCodecCapability: RTPCodecCapability{MimeTypeG722, 8000, 0, "", nil}, - PayloadType: 9, + PayloadType: rtp.PayloadTypeG722, }, { RTPCodecCapability: RTPCodecCapability{MimeTypePCMU, 8000, 0, "", nil}, - PayloadType: 0, + PayloadType: rtp.PayloadTypePCMU, }, { RTPCodecCapability: RTPCodecCapability{MimeTypePCMA, 8000, 0, "", nil}, - PayloadType: 8, + PayloadType: rtp.PayloadTypePCMA, }, } { if err := m.RegisterCodec(codec, RTPCodecTypeAudio); err != nil { @@ -106,7 +112,7 @@ func (m *MediaEngine) RegisterDefaultCodecs() error { PayloadType: 96, }, { - RTPCodecCapability: RTPCodecCapability{"video/rtx", 90000, 0, "apt=96", nil}, + RTPCodecCapability: RTPCodecCapability{MimeTypeRTX, 90000, 0, "apt=96", nil}, PayloadType: 97, }, @@ -115,7 +121,7 @@ func (m *MediaEngine) RegisterDefaultCodecs() error { PayloadType: 102, }, { - RTPCodecCapability: RTPCodecCapability{"video/rtx", 90000, 0, "apt=102", nil}, + RTPCodecCapability: RTPCodecCapability{MimeTypeRTX, 90000, 0, "apt=102", nil}, PayloadType: 103, }, @@ -124,7 +130,7 @@ func (m *MediaEngine) RegisterDefaultCodecs() error { PayloadType: 104, }, { - RTPCodecCapability: RTPCodecCapability{"video/rtx", 90000, 0, "apt=104", nil}, + RTPCodecCapability: RTPCodecCapability{MimeTypeRTX, 90000, 0, "apt=104", nil}, PayloadType: 105, }, @@ -133,7 +139,7 @@ func (m *MediaEngine) RegisterDefaultCodecs() error { PayloadType: 106, }, { - RTPCodecCapability: RTPCodecCapability{"video/rtx", 90000, 0, "apt=106", nil}, + RTPCodecCapability: RTPCodecCapability{MimeTypeRTX, 90000, 0, "apt=106", nil}, PayloadType: 107, }, @@ -142,7 +148,7 @@ func (m *MediaEngine) RegisterDefaultCodecs() error { PayloadType: 108, }, { - RTPCodecCapability: RTPCodecCapability{"video/rtx", 90000, 0, "apt=108", nil}, + RTPCodecCapability: RTPCodecCapability{MimeTypeRTX, 90000, 0, "apt=108", nil}, PayloadType: 109, }, @@ -151,7 +157,7 @@ func (m *MediaEngine) RegisterDefaultCodecs() error { PayloadType: 127, }, { - RTPCodecCapability: RTPCodecCapability{"video/rtx", 90000, 0, "apt=127", nil}, + RTPCodecCapability: RTPCodecCapability{MimeTypeRTX, 90000, 0, "apt=127", nil}, PayloadType: 125, }, @@ -160,7 +166,7 @@ func (m *MediaEngine) RegisterDefaultCodecs() error { PayloadType: 39, }, { - RTPCodecCapability: RTPCodecCapability{"video/rtx", 90000, 0, "apt=39", nil}, + RTPCodecCapability: RTPCodecCapability{MimeTypeRTX, 90000, 0, "apt=39", nil}, PayloadType: 40, }, @@ -169,7 +175,7 @@ func (m *MediaEngine) RegisterDefaultCodecs() error { PayloadType: 45, }, { - RTPCodecCapability: RTPCodecCapability{"video/rtx", 90000, 0, "apt=45", nil}, + RTPCodecCapability: RTPCodecCapability{MimeTypeRTX, 90000, 0, "apt=45", nil}, PayloadType: 46, }, @@ -178,7 +184,7 @@ func (m *MediaEngine) RegisterDefaultCodecs() error { PayloadType: 98, }, { - RTPCodecCapability: RTPCodecCapability{"video/rtx", 90000, 0, "apt=98", nil}, + RTPCodecCapability: RTPCodecCapability{MimeTypeRTX, 90000, 0, "apt=98", nil}, PayloadType: 99, }, @@ -187,7 +193,7 @@ func (m *MediaEngine) RegisterDefaultCodecs() error { PayloadType: 100, }, { - RTPCodecCapability: RTPCodecCapability{"video/rtx", 90000, 0, "apt=100", nil}, + RTPCodecCapability: RTPCodecCapability{MimeTypeRTX, 90000, 0, "apt=100", nil}, PayloadType: 101, }, @@ -196,7 +202,7 @@ func (m *MediaEngine) RegisterDefaultCodecs() error { PayloadType: 112, }, { - RTPCodecCapability: RTPCodecCapability{"video/rtx", 90000, 0, "apt=112", nil}, + RTPCodecCapability: RTPCodecCapability{MimeTypeRTX, 90000, 0, "apt=112", nil}, PayloadType: 113, }, } { @@ -286,13 +292,12 @@ func (m *MediaEngine) RegisterFeedback(feedback RTCPFeedback, typ RTPCodecType) m.mu.Lock() defer m.mu.Unlock() - switch typ { - case RTPCodecTypeVideo: + if typ == RTPCodecTypeVideo { for i, v := range m.videoCodecs { v.RTCPFeedback = append(v.RTCPFeedback, feedback) m.videoCodecs[i] = v } - case RTPCodecTypeAudio: + } else if typ == RTPCodecTypeAudio { for i, v := range m.audioCodecs { v.RTCPFeedback = append(v.RTCPFeedback, feedback) m.audioCodecs[i] = v @@ -703,3 +708,23 @@ func payloaderForCodec(codec RTPCodecCapability) (rtp.Payloader, error) { return nil, ErrNoPayloaderForCodec } } + +func (m *MediaEngine) isRTXEnabled(typ RTPCodecType, directions []RTPTransceiverDirection) bool { + for _, p := range m.getRTPParametersByKind(typ, directions).Codecs { + if p.MimeType == MimeTypeRTX { + return true + } + } + + return false +} + +func (m *MediaEngine) isFECEnabled(typ RTPCodecType, directions []RTPTransceiverDirection) bool { + for _, p := range m.getRTPParametersByKind(typ, directions).Codecs { + if strings.Contains(p.MimeType, MimeTypeFlexFEC) { + return true + } + } + + return false +} diff --git a/vendor/github.com/pion/webrtc/v3/networktype.go b/vendor/github.com/pion/webrtc/v4/networktype.go similarity index 87% rename from vendor/github.com/pion/webrtc/v3/networktype.go rename to vendor/github.com/pion/webrtc/v4/networktype.go index 601e73ff8d..7bf4862327 100644 --- a/vendor/github.com/pion/webrtc/v3/networktype.go +++ b/vendor/github.com/pion/webrtc/v4/networktype.go @@ -6,7 +6,7 @@ package webrtc import ( "fmt" - "github.com/pion/ice/v2" + "github.com/pion/ice/v4" ) func supportedNetworkTypes() []NetworkType { @@ -22,8 +22,11 @@ func supportedNetworkTypes() []NetworkType { type NetworkType int const ( + // NetworkTypeUnknown is the enum's zero-value + NetworkTypeUnknown NetworkType = iota + // NetworkTypeUDP4 indicates UDP over IPv4. - NetworkTypeUDP4 NetworkType = iota + 1 + NetworkTypeUDP4 // NetworkTypeUDP6 indicates UDP over IPv6. NetworkTypeUDP6 @@ -87,7 +90,7 @@ func NewNetworkType(raw string) (NetworkType, error) { case networkTypeTCP6Str: return NetworkTypeTCP6, nil default: - return NetworkType(Unknown), fmt.Errorf("%w: %s", errNetworkTypeUnknown, raw) + return NetworkTypeUnknown, fmt.Errorf("%w: %s", errNetworkTypeUnknown, raw) } } @@ -102,6 +105,6 @@ func getNetworkType(iceNetworkType ice.NetworkType) (NetworkType, error) { case ice.NetworkTypeTCP6: return NetworkTypeTCP6, nil default: - return NetworkType(Unknown), fmt.Errorf("%w: %s", errNetworkTypeUnknown, iceNetworkType.String()) + return NetworkTypeUnknown, fmt.Errorf("%w: %s", errNetworkTypeUnknown, iceNetworkType.String()) } } diff --git a/vendor/github.com/pion/webrtc/v3/oauthcredential.go b/vendor/github.com/pion/webrtc/v4/oauthcredential.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/oauthcredential.go rename to vendor/github.com/pion/webrtc/v4/oauthcredential.go diff --git a/vendor/github.com/pion/webrtc/v3/offeransweroptions.go b/vendor/github.com/pion/webrtc/v4/offeransweroptions.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/offeransweroptions.go rename to vendor/github.com/pion/webrtc/v4/offeransweroptions.go diff --git a/vendor/github.com/pion/webrtc/v3/operations.go b/vendor/github.com/pion/webrtc/v4/operations.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/operations.go rename to vendor/github.com/pion/webrtc/v4/operations.go diff --git a/vendor/github.com/pion/webrtc/v4/package.json b/vendor/github.com/pion/webrtc/v4/package.json new file mode 100644 index 0000000000..f58d23972b --- /dev/null +++ b/vendor/github.com/pion/webrtc/v4/package.json @@ -0,0 +1,12 @@ +{ + "name": "webrtc", + "repository": "git@github.com:pion/webrtc.git", + "private": true, + "devDependencies": { + "@roamhq/wrtc": "^0.8.0" + }, + "dependencies": { + "request": "2.88.2" + }, + "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" +} diff --git a/vendor/github.com/pion/webrtc/v3/peerconnection.go b/vendor/github.com/pion/webrtc/v4/peerconnection.go similarity index 96% rename from vendor/github.com/pion/webrtc/v3/peerconnection.go rename to vendor/github.com/pion/webrtc/v4/peerconnection.go index d515c08a7b..35823660d2 100644 --- a/vendor/github.com/pion/webrtc/v3/peerconnection.go +++ b/vendor/github.com/pion/webrtc/v4/peerconnection.go @@ -19,14 +19,14 @@ import ( "sync/atomic" "time" - "github.com/pion/ice/v2" + "github.com/pion/ice/v4" "github.com/pion/interceptor" "github.com/pion/logging" "github.com/pion/rtcp" "github.com/pion/sdp/v3" - "github.com/pion/srtp/v2" - "github.com/pion/webrtc/v3/internal/util" - "github.com/pion/webrtc/v3/pkg/rtcerr" + "github.com/pion/srtp/v3" + "github.com/pion/webrtc/v4/internal/util" + "github.com/pion/webrtc/v4/pkg/rtcerr" ) // PeerConnection represents a WebRTC connection that establishes a @@ -93,24 +93,13 @@ type PeerConnection struct { interceptorRTCPWriter interceptor.RTCPWriter } -// NewPeerConnection creates a PeerConnection with the default codecs and -// interceptors. See RegisterDefaultCodecs and RegisterDefaultInterceptors. +// NewPeerConnection creates a PeerConnection with the default codecs and interceptors. // -// If you wish to customize the set of available codecs or the set of -// active interceptors, create a MediaEngine and call api.NewPeerConnection -// instead of this function. +// If you wish to customize the set of available codecs and/or the set of active interceptors, +// create an API with a custom MediaEngine and/or interceptor.Registry, +// then call API.NewPeerConnection() instead of this function. func NewPeerConnection(configuration Configuration) (*PeerConnection, error) { - m := &MediaEngine{} - if err := m.RegisterDefaultCodecs(); err != nil { - return nil, err - } - - i := &interceptor.Registry{} - if err := RegisterDefaultInterceptors(m, i); err != nil { - return nil, err - } - - api := NewAPI(WithMediaEngine(m), WithInterceptorRegistry(i)) + api := NewAPI() return api.NewPeerConnection(configuration) } @@ -233,11 +222,11 @@ func (pc *PeerConnection) initConfiguration(configuration Configuration) error { pc.configuration.Certificates = []Certificate{*certificate} } - if configuration.BundlePolicy != BundlePolicy(Unknown) { + if configuration.BundlePolicy != BundlePolicyUnknown { pc.configuration.BundlePolicy = configuration.BundlePolicy } - if configuration.RTCPMuxPolicy != RTCPMuxPolicy(Unknown) { + if configuration.RTCPMuxPolicy != RTCPMuxPolicyUnknown { pc.configuration.RTCPMuxPolicy = configuration.RTCPMuxPolicy } @@ -245,13 +234,8 @@ func (pc *PeerConnection) initConfiguration(configuration Configuration) error { pc.configuration.ICECandidatePoolSize = configuration.ICECandidatePoolSize } - if configuration.ICETransportPolicy != ICETransportPolicy(Unknown) { - pc.configuration.ICETransportPolicy = configuration.ICETransportPolicy - } - - if configuration.SDPSemantics != SDPSemantics(Unknown) { - pc.configuration.SDPSemantics = configuration.SDPSemantics - } + pc.configuration.ICETransportPolicy = configuration.ICETransportPolicy + pc.configuration.SDPSemantics = configuration.SDPSemantics sanitizedICEServers := configuration.getICEServers() if len(sanitizedICEServers) > 0 { @@ -396,6 +380,14 @@ func (pc *PeerConnection) checkNegotiationNeeded() bool { //nolint:gocognit return true } track := sender.Track() + if track == nil { + // Situation when sender's track is nil could happen when + // a) replaceTrack(nil) is called + // b) removeTrack() is called, changing the transceiver's direction to inactive + // As t.Direction() in this branch is either sendrecv or sendonly, we believe (a) option is the case + // As calling replaceTrack does not require renegotiation, we skip check for this transceiver + continue + } if !okMsid || descMsid != track.StreamID()+" "+track.ID() { return true } @@ -442,8 +434,18 @@ func (pc *PeerConnection) OnICECandidate(f func(*ICECandidate)) { // OnICEGatheringStateChange sets an event handler which is invoked when the // ICE candidate gathering state has changed. -func (pc *PeerConnection) OnICEGatheringStateChange(f func(ICEGathererState)) { - pc.iceGatherer.OnStateChange(f) +func (pc *PeerConnection) OnICEGatheringStateChange(f func(ICEGatheringState)) { + pc.iceGatherer.OnStateChange( + func(gathererState ICEGathererState) { + switch gathererState { + case ICEGathererStateGathering: + f(ICEGatheringStateGathering) + case ICEGathererStateComplete: + f(ICEGatheringStateComplete) + default: + // Other states ignored + } + }) } // OnTrack sets an event handler which is called when remote track @@ -527,7 +529,7 @@ func (pc *PeerConnection) SetConfiguration(configuration Configuration) error { } // https://www.w3.org/TR/webrtc/#set-the-configuration (step #5) - if configuration.BundlePolicy != BundlePolicy(Unknown) { + if configuration.BundlePolicy != BundlePolicyUnknown { if configuration.BundlePolicy != pc.configuration.BundlePolicy { return &rtcerr.InvalidModificationError{Err: ErrModifyingBundlePolicy} } @@ -535,7 +537,7 @@ func (pc *PeerConnection) SetConfiguration(configuration Configuration) error { } // https://www.w3.org/TR/webrtc/#set-the-configuration (step #6) - if configuration.RTCPMuxPolicy != RTCPMuxPolicy(Unknown) { + if configuration.RTCPMuxPolicy != RTCPMuxPolicyUnknown { if configuration.RTCPMuxPolicy != pc.configuration.RTCPMuxPolicy { return &rtcerr.InvalidModificationError{Err: ErrModifyingRTCPMuxPolicy} } @@ -552,9 +554,7 @@ func (pc *PeerConnection) SetConfiguration(configuration Configuration) error { } // https://www.w3.org/TR/webrtc/#set-the-configuration (step #8) - if configuration.ICETransportPolicy != ICETransportPolicy(Unknown) { - pc.configuration.ICETransportPolicy = configuration.ICETransportPolicy - } + pc.configuration.ICETransportPolicy = configuration.ICETransportPolicy // https://www.w3.org/TR/webrtc/#set-the-configuration (step #11) if len(configuration.ICEServers) > 0 { @@ -857,7 +857,7 @@ func (pc *PeerConnection) setDescription(sd *SessionDescription, op stateChangeO switch { case pc.isClosed.get(): return &rtcerr.InvalidStateError{Err: ErrConnectionClosed} - case NewSDPType(sd.Type.String()) == SDPType(Unknown): + case NewSDPType(sd.Type.String()) == SDPTypeUnknown: return &rtcerr.TypeError{Err: fmt.Errorf("%w: '%d' is not a valid enum value of type SDPType", errPeerConnSDPTypeInvalidValue, sd.Type)} } @@ -1048,6 +1048,11 @@ func (pc *PeerConnection) SetRemoteDescription(desc SessionDescription) error { return err } + // Disable RTX/FEC on RTPSenders if the remote didn't support it + for _, sender := range pc.GetSenders() { + sender.configureRTXAndFEC() + } + var t *RTPTransceiver localTransceivers := append([]*RTPTransceiver{}, pc.GetTransceivers()...) detectedPlanB := descriptionIsPlanB(pc.RemoteDescription(), pc.log) @@ -1070,7 +1075,7 @@ func (pc *PeerConnection) SetRemoteDescription(desc SessionDescription) error { kind := NewRTPCodecType(media.MediaName.Media) direction := getPeerDirection(media) - if kind == 0 || direction == RTPTransceiverDirection(Unknown) { + if kind == 0 || direction == RTPTransceiverDirectionUnknown { continue } @@ -1278,7 +1283,7 @@ func setRTPTransceiverCurrentDirection(answer *SessionDescription, currentTransc } direction := getPeerDirection(media) - if direction == RTPTransceiverDirection(Unknown) { + if direction == RTPTransceiverDirectionUnknown { continue } @@ -1330,7 +1335,7 @@ func runIfNewReceiver( return false } -// configurepRTPReceivers opens knows inbound SRTP streams from the RemoteDescription +// configureRTPReceivers opens knows inbound SRTP streams from the RemoteDescription func (pc *PeerConnection) configureRTPReceivers(isRenegotiation bool, remoteDesc *SessionDescription, currentTransceivers []*RTPTransceiver) { //nolint:gocognit incomingTracks := trackDetailsFromSDP(pc.log, remoteDesc.parsed) @@ -1616,7 +1621,7 @@ func (pc *PeerConnection) handleIncomingSSRC(rtpStream io.Reader, ssrc SSRC) err return err } - streamInfo := createStreamInfo("", ssrc, params.Codecs[0].PayloadType, params.Codecs[0].RTPCodecCapability, params.HeaderExtensions) + streamInfo := createStreamInfo("", ssrc, 0, 0, params.Codecs[0].PayloadType, 0, 0, params.Codecs[0].RTPCodecCapability, params.HeaderExtensions) readStream, interceptor, rtcpReadStream, rtcpInterceptor, err := pc.dtlsTransport.streamsForSSRC(ssrc, *streamInfo) if err != nil { return err @@ -1911,7 +1916,7 @@ func (pc *PeerConnection) RemoveTrack(sender *RTPSender) (err error) { return } -func (pc *PeerConnection) newTransceiverFromTrack(direction RTPTransceiverDirection, track TrackLocal) (t *RTPTransceiver, err error) { +func (pc *PeerConnection) newTransceiverFromTrack(direction RTPTransceiverDirection, track TrackLocal, init ...RTPTransceiverInit) (t *RTPTransceiver, err error) { var ( r *RTPReceiver s *RTPSender @@ -1931,6 +1936,13 @@ func (pc *PeerConnection) newTransceiverFromTrack(direction RTPTransceiverDirect if err != nil { return } + + // Allow RTPTransceiverInit to override SSRC + if s != nil && len(s.trackEncodings) == 1 && + len(init) == 1 && len(init[0].SendEncodings) == 1 && init[0].SendEncodings[0].SSRC != 0 { + s.trackEncodings[0].ssrc = init[0].SendEncodings[0].SSRC + } + return newRTPTransceiver(r, s, direction, track.Kind(), pc.api), nil } @@ -1956,7 +1968,7 @@ func (pc *PeerConnection) AddTransceiverFromKind(kind RTPCodecType, init ...RTPT if err != nil { return nil, err } - t, err = pc.newTransceiverFromTrack(direction, track) + t, err = pc.newTransceiverFromTrack(direction, track, init...) if err != nil { return nil, err } @@ -1988,7 +2000,7 @@ func (pc *PeerConnection) AddTransceiverFromTrack(track TrackLocal, init ...RTPT direction = init[0].Direction } - t, err = pc.newTransceiverFromTrack(direction, track) + t, err = pc.newTransceiverFromTrack(direction, track, init...) if err == nil { pc.mu.Lock() pc.addRTPTransceiver(t) @@ -2062,6 +2074,9 @@ func (pc *PeerConnection) CreateDataChannel(label string, options *DataChannelIn pc.sctpTransport.lock.Lock() pc.sctpTransport.dataChannels = append(pc.sctpTransport.dataChannels, d) + if d.ID() != nil { + pc.sctpTransport.dataChannelIDsUsed[*d.ID()] = struct{}{} + } pc.sctpTransport.dataChannelsRequested++ pc.sctpTransport.lock.Unlock() @@ -2397,6 +2412,19 @@ func (pc *PeerConnection) startTransports(iceRole ICERole, dtlsRole DTLSRole, re return } + pc.dtlsTransport.internalOnCloseHandler = func() { + if pc.isClosed.get() { + return + } + + pc.log.Info("Closing PeerConnection from DTLS CloseNotify") + go func() { + if pcClosErr := pc.Close(); pcClosErr != nil { + pc.log.Warnf("Failed to close PeerConnection from DTLS CloseNotify: %s", pcClosErr) + } + }() + } + // Start the dtls transport err = pc.dtlsTransport.Start(DTLSParameters{ Role: dtlsRole, @@ -2542,7 +2570,7 @@ func (pc *PeerConnection) generateMatchedSDP(transceivers []*RTPTransceiver, use kind := NewRTPCodecType(media.MediaName.Media) direction := getPeerDirection(media) - if kind == 0 || direction == RTPTransceiverDirection(Unknown) { + if kind == 0 || direction == RTPTransceiverDirectionUnknown { continue } diff --git a/vendor/github.com/pion/webrtc/v3/peerconnection_js.go b/vendor/github.com/pion/webrtc/v4/peerconnection_js.go similarity index 99% rename from vendor/github.com/pion/webrtc/v3/peerconnection_js.go rename to vendor/github.com/pion/webrtc/v4/peerconnection_js.go index 8322e1be92..493afa02a0 100644 --- a/vendor/github.com/pion/webrtc/v3/peerconnection_js.go +++ b/vendor/github.com/pion/webrtc/v4/peerconnection_js.go @@ -10,8 +10,8 @@ package webrtc import ( "syscall/js" - "github.com/pion/ice/v2" - "github.com/pion/webrtc/v3/pkg/rtcerr" + "github.com/pion/ice/v4" + "github.com/pion/webrtc/v4/pkg/rtcerr" ) // PeerConnection represents a WebRTC connection that establishes a @@ -182,14 +182,14 @@ func (pc *PeerConnection) checkConfiguration(configuration Configuration) error // } // https://www.w3.org/TR/webrtc/#set-the-configuration (step #5) - if configuration.BundlePolicy != BundlePolicy(Unknown) { + if configuration.BundlePolicy != BundlePolicyUnknown { if configuration.BundlePolicy != existingConfig.BundlePolicy { return &rtcerr.InvalidModificationError{Err: ErrModifyingBundlePolicy} } } // https://www.w3.org/TR/webrtc/#set-the-configuration (step #6) - if configuration.RTCPMuxPolicy != RTCPMuxPolicy(Unknown) { + if configuration.RTCPMuxPolicy != RTCPMuxPolicyUnknown { if configuration.RTCPMuxPolicy != existingConfig.RTCPMuxPolicy { return &rtcerr.InvalidModificationError{Err: ErrModifyingRTCPMuxPolicy} } diff --git a/vendor/github.com/pion/webrtc/v3/peerconnectionstate.go b/vendor/github.com/pion/webrtc/v4/peerconnectionstate.go similarity index 94% rename from vendor/github.com/pion/webrtc/v3/peerconnectionstate.go rename to vendor/github.com/pion/webrtc/v4/peerconnectionstate.go index b626a31e32..0ff24afca0 100644 --- a/vendor/github.com/pion/webrtc/v3/peerconnectionstate.go +++ b/vendor/github.com/pion/webrtc/v4/peerconnectionstate.go @@ -7,11 +7,14 @@ package webrtc type PeerConnectionState int const ( + // PeerConnectionStateUnknown is the enum's zero-value + PeerConnectionStateUnknown PeerConnectionState = iota + // PeerConnectionStateNew indicates that any of the ICETransports or // DTLSTransports are in the "new" state and none of the transports are // in the "connecting", "checking", "failed" or "disconnected" state, or // all transports are in the "closed" state, or there are no transports. - PeerConnectionStateNew PeerConnectionState = iota + 1 + PeerConnectionStateNew // PeerConnectionStateConnecting indicates that any of the // ICETransports or DTLSTransports are in the "connecting" or @@ -62,7 +65,7 @@ func newPeerConnectionState(raw string) PeerConnectionState { case peerConnectionStateClosedStr: return PeerConnectionStateClosed default: - return PeerConnectionState(Unknown) + return PeerConnectionStateUnknown } } diff --git a/vendor/github.com/pion/webrtc/v3/pkg/media/media.go b/vendor/github.com/pion/webrtc/v4/pkg/media/media.go similarity index 82% rename from vendor/github.com/pion/webrtc/v3/pkg/media/media.go rename to vendor/github.com/pion/webrtc/v4/pkg/media/media.go index 386e65de3e..ab07e31897 100644 --- a/vendor/github.com/pion/webrtc/v3/pkg/media/media.go +++ b/vendor/github.com/pion/webrtc/v4/pkg/media/media.go @@ -18,6 +18,10 @@ type Sample struct { PacketTimestamp uint32 PrevDroppedPackets uint16 Metadata interface{} + + // RTP headers of RTP packets forming this Sample. (Optional) + // Useful for accessing RTP extensions associated to the Sample. + RTPHeaders []*rtp.Header } // Writer defines an interface to handle diff --git a/vendor/github.com/pion/webrtc/v3/pkg/rtcerr/errors.go b/vendor/github.com/pion/webrtc/v4/pkg/rtcerr/errors.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/pkg/rtcerr/errors.go rename to vendor/github.com/pion/webrtc/v4/pkg/rtcerr/errors.go diff --git a/vendor/github.com/pion/webrtc/v3/renovate.json b/vendor/github.com/pion/webrtc/v4/renovate.json similarity index 100% rename from vendor/github.com/pion/webrtc/v3/renovate.json rename to vendor/github.com/pion/webrtc/v4/renovate.json diff --git a/vendor/github.com/pion/webrtc/v3/rtcpfeedback.go b/vendor/github.com/pion/webrtc/v4/rtcpfeedback.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/rtcpfeedback.go rename to vendor/github.com/pion/webrtc/v4/rtcpfeedback.go diff --git a/vendor/github.com/pion/webrtc/v3/rtcpmuxpolicy.go b/vendor/github.com/pion/webrtc/v4/rtcpmuxpolicy.go similarity index 92% rename from vendor/github.com/pion/webrtc/v3/rtcpmuxpolicy.go rename to vendor/github.com/pion/webrtc/v4/rtcpmuxpolicy.go index bd68ab562c..ec84ea9132 100644 --- a/vendor/github.com/pion/webrtc/v3/rtcpmuxpolicy.go +++ b/vendor/github.com/pion/webrtc/v4/rtcpmuxpolicy.go @@ -12,11 +12,14 @@ import ( type RTCPMuxPolicy int const ( + // RTCPMuxPolicyUnknown is the enum's zero-value + RTCPMuxPolicyUnknown RTCPMuxPolicy = iota + // RTCPMuxPolicyNegotiate indicates to gather ICE candidates for both // RTP and RTCP candidates. If the remote-endpoint is capable of // multiplexing RTCP, multiplex RTCP on the RTP candidates. If it is not, // use both the RTP and RTCP candidates separately. - RTCPMuxPolicyNegotiate RTCPMuxPolicy = iota + 1 + RTCPMuxPolicyNegotiate // RTCPMuxPolicyRequire indicates to gather ICE candidates only for // RTP and multiplex RTCP on the RTP candidates. If the remote endpoint is @@ -37,7 +40,7 @@ func newRTCPMuxPolicy(raw string) RTCPMuxPolicy { case rtcpMuxPolicyRequireStr: return RTCPMuxPolicyRequire default: - return RTCPMuxPolicy(Unknown) + return RTCPMuxPolicyUnknown } } diff --git a/vendor/github.com/pion/webrtc/v3/rtpcapabilities.go b/vendor/github.com/pion/webrtc/v4/rtpcapabilities.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/rtpcapabilities.go rename to vendor/github.com/pion/webrtc/v4/rtpcapabilities.go diff --git a/vendor/github.com/pion/webrtc/v3/rtpcodec.go b/vendor/github.com/pion/webrtc/v4/rtpcodec.go similarity index 87% rename from vendor/github.com/pion/webrtc/v3/rtpcodec.go rename to vendor/github.com/pion/webrtc/v4/rtpcodec.go index 4b8f81c4e7..68beae8d39 100644 --- a/vendor/github.com/pion/webrtc/v3/rtpcodec.go +++ b/vendor/github.com/pion/webrtc/v4/rtpcodec.go @@ -4,18 +4,21 @@ package webrtc import ( + "fmt" "strings" - "github.com/pion/webrtc/v3/internal/fmtp" + "github.com/pion/webrtc/v4/internal/fmtp" ) // RTPCodecType determines the type of a codec type RTPCodecType int const ( + // RTPCodecTypeUnknown is the enum's zero-value + RTPCodecTypeUnknown RTPCodecType = iota // RTPCodecTypeAudio indicates this is an audio codec - RTPCodecTypeAudio RTPCodecType = iota + 1 + RTPCodecTypeAudio // RTPCodecTypeVideo indicates this is a video codec RTPCodecTypeVideo @@ -121,3 +124,15 @@ func codecParametersFuzzySearch(needle RTPCodecParameters, haystack []RTPCodecPa return RTPCodecParameters{}, codecMatchNone } + +// Given a CodecParameters find the RTX CodecParameters if one exists +func findRTXPayloadType(needle PayloadType, haystack []RTPCodecParameters) PayloadType { + aptStr := fmt.Sprintf("apt=%d", needle) + for _, c := range haystack { + if aptStr == c.SDPFmtpLine { + return c.PayloadType + } + } + + return PayloadType(0) +} diff --git a/vendor/github.com/pion/webrtc/v3/rtpcodingparameters.go b/vendor/github.com/pion/webrtc/v4/rtpcodingparameters.go similarity index 74% rename from vendor/github.com/pion/webrtc/v3/rtpcodingparameters.go rename to vendor/github.com/pion/webrtc/v4/rtpcodingparameters.go index f03d8c35f4..fa39a631d4 100644 --- a/vendor/github.com/pion/webrtc/v3/rtpcodingparameters.go +++ b/vendor/github.com/pion/webrtc/v4/rtpcodingparameters.go @@ -9,6 +9,12 @@ type RTPRtxParameters struct { SSRC SSRC `json:"ssrc"` } +// RTPFecParameters dictionary contains information relating to forward error correction (FEC) settings. +// https://draft.ortc.org/#dom-rtcrtpfecparameters +type RTPFecParameters struct { + SSRC SSRC `json:"ssrc"` +} + // RTPCodingParameters provides information relating to both encoding and decoding. // This is a subset of the RFC since Pion WebRTC doesn't implement encoding/decoding itself // http://draft.ortc.org/#dom-rtcrtpcodingparameters @@ -17,4 +23,5 @@ type RTPCodingParameters struct { SSRC SSRC `json:"ssrc"` PayloadType PayloadType `json:"payloadType"` RTX RTPRtxParameters `json:"rtx"` + FEC RTPFecParameters `json:"fec"` } diff --git a/vendor/github.com/pion/webrtc/v3/rtpdecodingparameters.go b/vendor/github.com/pion/webrtc/v4/rtpdecodingparameters.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/rtpdecodingparameters.go rename to vendor/github.com/pion/webrtc/v4/rtpdecodingparameters.go diff --git a/vendor/github.com/pion/webrtc/v3/rtpencodingparameters.go b/vendor/github.com/pion/webrtc/v4/rtpencodingparameters.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/rtpencodingparameters.go rename to vendor/github.com/pion/webrtc/v4/rtpencodingparameters.go diff --git a/vendor/github.com/pion/webrtc/v3/rtpreceiveparameters.go b/vendor/github.com/pion/webrtc/v4/rtpreceiveparameters.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/rtpreceiveparameters.go rename to vendor/github.com/pion/webrtc/v4/rtpreceiveparameters.go diff --git a/vendor/github.com/pion/webrtc/v3/rtpreceiver.go b/vendor/github.com/pion/webrtc/v4/rtpreceiver.go similarity index 96% rename from vendor/github.com/pion/webrtc/v3/rtpreceiver.go rename to vendor/github.com/pion/webrtc/v4/rtpreceiver.go index 28d72246da..ba1afb5517 100644 --- a/vendor/github.com/pion/webrtc/v3/rtpreceiver.go +++ b/vendor/github.com/pion/webrtc/v4/rtpreceiver.go @@ -15,8 +15,8 @@ import ( "github.com/pion/interceptor" "github.com/pion/rtcp" - "github.com/pion/srtp/v2" - "github.com/pion/webrtc/v3/internal/util" + "github.com/pion/srtp/v3" + "github.com/pion/webrtc/v4/internal/util" ) // trackStreams maintains a mapping of RTP/RTCP streams to a specific track @@ -210,14 +210,14 @@ func (r *RTPReceiver) startReceive(parameters RTPReceiveParameters) error { return fmt.Errorf("%w: %d", errRTPReceiverWithSSRCTrackStreamNotFound, parameters.Encodings[i].SSRC) } - t.streamInfo = createStreamInfo("", parameters.Encodings[i].SSRC, 0, codec, globalParams.HeaderExtensions) + t.streamInfo = createStreamInfo("", parameters.Encodings[i].SSRC, 0, 0, 0, 0, 0, codec, globalParams.HeaderExtensions) var err error if t.rtpReadStream, t.rtpInterceptor, t.rtcpReadStream, t.rtcpInterceptor, err = r.transport.streamsForSSRC(parameters.Encodings[i].SSRC, *t.streamInfo); err != nil { return err } if rtxSsrc := parameters.Encodings[i].RTX.SSRC; rtxSsrc != 0 { - streamInfo := createStreamInfo("", rtxSsrc, 0, codec, globalParams.HeaderExtensions) + streamInfo := createStreamInfo("", rtxSsrc, 0, 0, 0, 0, 0, codec, globalParams.HeaderExtensions) rtpReadStream, rtpInterceptor, rtcpReadStream, rtcpInterceptor, err := r.transport.streamsForSSRC(rtxSsrc, *streamInfo) if err != nil { return err @@ -252,12 +252,21 @@ func (r *RTPReceiver) Read(b []byte) (n int, a interceptor.Attributes, err error func (r *RTPReceiver) ReadSimulcast(b []byte, rid string) (n int, a interceptor.Attributes, err error) { select { case <-r.received: + var rtcpInterceptor interceptor.RTCPReader + + r.mu.Lock() for _, t := range r.tracks { if t.track != nil && t.track.rid == rid { - return t.rtcpInterceptor.Read(b, a) + rtcpInterceptor = t.rtcpInterceptor } } - return 0, nil, fmt.Errorf("%w: %s", errRTPReceiverForRIDTrackStreamNotFound, rid) + r.mu.Unlock() + + if rtcpInterceptor == nil { + return 0, nil, fmt.Errorf("%w: %s", errRTPReceiverForRIDTrackStreamNotFound, rid) + } + return rtcpInterceptor.Read(b, a) + case <-r.closed: return 0, nil, io.ErrClosedPipe } diff --git a/vendor/github.com/pion/webrtc/v3/rtpreceiver_go.go b/vendor/github.com/pion/webrtc/v4/rtpreceiver_go.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/rtpreceiver_go.go rename to vendor/github.com/pion/webrtc/v4/rtpreceiver_go.go diff --git a/vendor/github.com/pion/webrtc/v3/rtpreceiver_js.go b/vendor/github.com/pion/webrtc/v4/rtpreceiver_js.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/rtpreceiver_js.go rename to vendor/github.com/pion/webrtc/v4/rtpreceiver_js.go diff --git a/vendor/github.com/pion/webrtc/v3/rtpsender.go b/vendor/github.com/pion/webrtc/v4/rtpsender.go similarity index 81% rename from vendor/github.com/pion/webrtc/v3/rtpsender.go rename to vendor/github.com/pion/webrtc/v4/rtpsender.go index 0c0e867ecd..b50ad865c1 100644 --- a/vendor/github.com/pion/webrtc/v3/rtpsender.go +++ b/vendor/github.com/pion/webrtc/v4/rtpsender.go @@ -16,7 +16,7 @@ import ( "github.com/pion/randutil" "github.com/pion/rtcp" "github.com/pion/rtp" - "github.com/pion/webrtc/v3/internal/util" + "github.com/pion/webrtc/v4/internal/util" ) type trackEncoding struct { @@ -29,7 +29,7 @@ type trackEncoding struct { context *baseTrackLocalContext - ssrc SSRC + ssrc, ssrcRTX, ssrcFEC SSRC } // RTPSender allows an application to control how a given Track is encoded and transmitted to a remote peer @@ -110,7 +110,12 @@ func (r *RTPSender) Transport() *DTLSTransport { return r.transport } -func (r *RTPSender) getParameters() RTPSendParameters { +// GetParameters describes the current configuration for the encoding and +// transmission of media on the sender's track. +func (r *RTPSender) GetParameters() RTPSendParameters { + r.mu.RLock() + defer r.mu.RUnlock() + var encodings []RTPEncodingParameters for _, trackEncoding := range r.trackEncodings { var rid string @@ -121,6 +126,8 @@ func (r *RTPSender) getParameters() RTPSendParameters { RTPCodingParameters: RTPCodingParameters{ RID: rid, SSRC: trackEncoding.ssrc, + RTX: RTPRtxParameters{SSRC: trackEncoding.ssrcRTX}, + FEC: RTPFecParameters{SSRC: trackEncoding.ssrcFEC}, PayloadType: r.payloadType, }, }) @@ -140,14 +147,6 @@ func (r *RTPSender) getParameters() RTPSendParameters { return sendParameters } -// GetParameters describes the current configuration for the encoding and -// transmission of media on the sender's track. -func (r *RTPSender) GetParameters() RTPSendParameters { - r.mu.RLock() - defer r.mu.RUnlock() - return r.getParameters() -} - // AddEncoding adds an encoding to RTPSender. Used by simulcast senders. func (r *RTPSender) AddEncoding(track TrackLocal) error { r.mu.Lock() @@ -196,19 +195,18 @@ func (r *RTPSender) AddEncoding(track TrackLocal) error { } func (r *RTPSender) addEncoding(track TrackLocal) { - ssrc := SSRC(randutil.NewMathRandomGenerator().Uint32()) trackEncoding := &trackEncoding{ - track: track, - srtpStream: &srtpWriterFuture{ssrc: ssrc}, - ssrc: ssrc, - } - trackEncoding.srtpStream.rtpSender = r - trackEncoding.rtcpInterceptor = r.api.interceptor.BindRTCPReader( - interceptor.RTCPReaderFunc(func(in []byte, a interceptor.Attributes) (n int, attributes interceptor.Attributes, err error) { - n, err = trackEncoding.srtpStream.Read(in) - return n, a, err - }), - ) + track: track, + ssrc: SSRC(util.RandUint32()), + } + + if r.api.mediaEngine.isRTXEnabled(r.kind, []RTPTransceiverDirection{RTPTransceiverDirectionSendonly}) { + trackEncoding.ssrcRTX = SSRC(util.RandUint32()) + } + + if r.api.mediaEngine.isFECEnabled(r.kind, []RTPTransceiverDirection{RTPTransceiverDirectionSendonly}) { + trackEncoding.ssrcFEC = SSRC(util.RandUint32()) + } r.trackEncodings = append(r.trackEncodings, trackEncoding) } @@ -267,6 +265,8 @@ func (r *RTPSender) ReplaceTrack(track TrackLocal) error { id: context.ID(), params: r.api.mediaEngine.getRTPParametersByKind(track.Kind(), []RTPTransceiverDirection{RTPTransceiverDirectionSendonly}), ssrc: context.SSRC(), + ssrcRTX: context.SSRCRetransmission(), + ssrcFEC: context.SSRCForwardErrorCorrection(), writeStream: context.WriteStream(), rtcpInterceptor: context.RTCPReader(), }) @@ -301,12 +301,22 @@ func (r *RTPSender) Send(parameters RTPSendParameters) error { return errRTPSenderTrackRemoved } - for idx, trackEncoding := range r.trackEncodings { + for idx := range r.trackEncodings { + trackEncoding := r.trackEncodings[idx] + srtpStream := &srtpWriterFuture{ssrc: parameters.Encodings[idx].SSRC, rtpSender: r} writeStream := &interceptorToTrackLocalWriter{} + rtpParameters := r.api.mediaEngine.getRTPParametersByKind(trackEncoding.track.Kind(), []RTPTransceiverDirection{RTPTransceiverDirectionSendonly}) + + trackEncoding.srtpStream = srtpStream + trackEncoding.ssrc = parameters.Encodings[idx].SSRC + trackEncoding.ssrcRTX = parameters.Encodings[idx].RTX.SSRC + trackEncoding.ssrcFEC = parameters.Encodings[idx].FEC.SSRC trackEncoding.context = &baseTrackLocalContext{ id: r.id, - params: r.api.mediaEngine.getRTPParametersByKind(trackEncoding.track.Kind(), []RTPTransceiverDirection{RTPTransceiverDirectionSendonly}), + params: rtpParameters, ssrc: parameters.Encodings[idx].SSRC, + ssrcFEC: parameters.Encodings[idx].FEC.SSRC, + ssrcRTX: parameters.Encodings[idx].RTX.SSRC, writeStream: writeStream, rtcpInterceptor: trackEncoding.rtcpInterceptor, } @@ -320,17 +330,29 @@ func (r *RTPSender) Send(parameters RTPSendParameters) error { trackEncoding.streamInfo = *createStreamInfo( r.id, parameters.Encodings[idx].SSRC, + parameters.Encodings[idx].RTX.SSRC, + parameters.Encodings[idx].FEC.SSRC, codec.PayloadType, + findRTXPayloadType(codec.PayloadType, rtpParameters.Codecs), + 0, codec.RTPCodecCapability, parameters.HeaderExtensions, ) - srtpStream := trackEncoding.srtpStream + + trackEncoding.rtcpInterceptor = r.api.interceptor.BindRTCPReader( + interceptor.RTCPReaderFunc(func(in []byte, a interceptor.Attributes) (n int, attributes interceptor.Attributes, err error) { + n, err = trackEncoding.srtpStream.Read(in) + return n, a, err + }), + ) + rtpInterceptor := r.api.interceptor.BindLocalStream( &trackEncoding.streamInfo, - interceptor.RTPWriterFunc(func(header *rtp.Header, payload []byte, attributes interceptor.Attributes) (int, error) { + interceptor.RTPWriterFunc(func(header *rtp.Header, payload []byte, _ interceptor.Attributes) (int, error) { return srtpStream.WriteRTP(header, payload) }), ) + writeStream.interceptor.Store(rtpInterceptor) } @@ -361,7 +383,9 @@ func (r *RTPSender) Stop() error { errs := []error{} for _, trackEncoding := range r.trackEncodings { r.api.interceptor.UnbindLocalStream(&trackEncoding.streamInfo) - errs = append(errs, trackEncoding.srtpStream.Close()) + if trackEncoding.srtpStream != nil { + errs = append(errs, trackEncoding.srtpStream.Close()) + } } return util.FlattenErrs(errs) @@ -458,3 +482,20 @@ func (r *RTPSender) hasStopped() bool { return false } } + +// Set a SSRC for FEC and RTX if MediaEngine has them enabled +// If the remote doesn't support FEC or RTX we disable locally +func (r *RTPSender) configureRTXAndFEC() { + r.mu.RLock() + defer r.mu.RUnlock() + + for _, trackEncoding := range r.trackEncodings { + if !r.api.mediaEngine.isRTXEnabled(r.kind, []RTPTransceiverDirection{RTPTransceiverDirectionSendonly}) { + trackEncoding.ssrcRTX = SSRC(0) + } + + if !r.api.mediaEngine.isFECEnabled(r.kind, []RTPTransceiverDirection{RTPTransceiverDirectionSendonly}) { + trackEncoding.ssrcFEC = SSRC(0) + } + } +} diff --git a/vendor/github.com/pion/webrtc/v3/rtpsender_js.go b/vendor/github.com/pion/webrtc/v4/rtpsender_js.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/rtpsender_js.go rename to vendor/github.com/pion/webrtc/v4/rtpsender_js.go diff --git a/vendor/github.com/pion/webrtc/v3/rtpsendparameters.go b/vendor/github.com/pion/webrtc/v4/rtpsendparameters.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/rtpsendparameters.go rename to vendor/github.com/pion/webrtc/v4/rtpsendparameters.go diff --git a/vendor/github.com/pion/webrtc/v3/rtptransceiver.go b/vendor/github.com/pion/webrtc/v4/rtptransceiver.go similarity index 98% rename from vendor/github.com/pion/webrtc/v3/rtptransceiver.go rename to vendor/github.com/pion/webrtc/v4/rtptransceiver.go index f601a4102a..4ba732e8a1 100644 --- a/vendor/github.com/pion/webrtc/v3/rtptransceiver.go +++ b/vendor/github.com/pion/webrtc/v4/rtptransceiver.go @@ -42,7 +42,7 @@ func newRTPTransceiver( t.setReceiver(receiver) t.setSender(sender) t.setDirection(direction) - t.setCurrentDirection(RTPTransceiverDirection(Unknown)) + t.setCurrentDirection(RTPTransceiverDirectionUnknown) return t } @@ -193,7 +193,7 @@ func (t *RTPTransceiver) getCurrentDirection() RTPTransceiverDirection { if v, ok := t.currentDirection.Load().(RTPTransceiverDirection); ok { return v } - return RTPTransceiverDirection(Unknown) + return RTPTransceiverDirectionUnknown } func (t *RTPTransceiver) setSendingTrack(track TrackLocal) error { diff --git a/vendor/github.com/pion/webrtc/v3/rtptransceiver_js.go b/vendor/github.com/pion/webrtc/v4/rtptransceiver_js.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/rtptransceiver_js.go rename to vendor/github.com/pion/webrtc/v4/rtptransceiver_js.go diff --git a/vendor/github.com/pion/webrtc/v3/rtptransceiverdirection.go b/vendor/github.com/pion/webrtc/v4/rtptransceiverdirection.go similarity index 92% rename from vendor/github.com/pion/webrtc/v3/rtptransceiverdirection.go rename to vendor/github.com/pion/webrtc/v4/rtptransceiverdirection.go index 752cd5b9c6..5e1a5be1bc 100644 --- a/vendor/github.com/pion/webrtc/v3/rtptransceiverdirection.go +++ b/vendor/github.com/pion/webrtc/v4/rtptransceiverdirection.go @@ -7,9 +7,12 @@ package webrtc type RTPTransceiverDirection int const ( + // RTPTransceiverDirectionUnknown is the enum's zero-value + RTPTransceiverDirectionUnknown RTPTransceiverDirection = iota + // RTPTransceiverDirectionSendrecv indicates the RTPSender will offer // to send RTP and the RTPReceiver will offer to receive RTP. - RTPTransceiverDirectionSendrecv RTPTransceiverDirection = iota + 1 + RTPTransceiverDirectionSendrecv // RTPTransceiverDirectionSendonly indicates the RTPSender will offer // to send RTP. @@ -45,7 +48,7 @@ func NewRTPTransceiverDirection(raw string) RTPTransceiverDirection { case rtpTransceiverDirectionInactiveStr: return RTPTransceiverDirectionInactive default: - return RTPTransceiverDirection(Unknown) + return RTPTransceiverDirectionUnknown } } diff --git a/vendor/github.com/pion/webrtc/v3/rtptransceiverinit.go b/vendor/github.com/pion/webrtc/v4/rtptransceiverinit.go similarity index 67% rename from vendor/github.com/pion/webrtc/v3/rtptransceiverinit.go rename to vendor/github.com/pion/webrtc/v4/rtptransceiverinit.go index 3aac1dc14c..1ad9bb606d 100644 --- a/vendor/github.com/pion/webrtc/v3/rtptransceiverinit.go +++ b/vendor/github.com/pion/webrtc/v4/rtptransceiverinit.go @@ -9,7 +9,3 @@ type RTPTransceiverInit struct { SendEncodings []RTPEncodingParameters // Streams []*Track } - -// RtpTransceiverInit is a temporary mapping while we fix case sensitivity -// Deprecated: Use RTPTransceiverInit instead -type RtpTransceiverInit = RTPTransceiverInit //nolint: stylecheck,golint diff --git a/vendor/github.com/pion/webrtc/v3/sctpcapabilities.go b/vendor/github.com/pion/webrtc/v4/sctpcapabilities.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/sctpcapabilities.go rename to vendor/github.com/pion/webrtc/v4/sctpcapabilities.go diff --git a/vendor/github.com/pion/webrtc/v3/sctptransport.go b/vendor/github.com/pion/webrtc/v4/sctptransport.go similarity index 92% rename from vendor/github.com/pion/webrtc/v3/sctptransport.go rename to vendor/github.com/pion/webrtc/v4/sctptransport.go index 8167423b7e..68f40b9079 100644 --- a/vendor/github.com/pion/webrtc/v3/sctptransport.go +++ b/vendor/github.com/pion/webrtc/v4/sctptransport.go @@ -16,7 +16,7 @@ import ( "github.com/pion/datachannel" "github.com/pion/logging" "github.com/pion/sctp" - "github.com/pion/webrtc/v3/pkg/rtcerr" + "github.com/pion/webrtc/v4/pkg/rtcerr" ) const sctpMaxChannels = uint16(65535) @@ -53,6 +53,7 @@ type SCTPTransport struct { // DataChannels dataChannels []*DataChannel + dataChannelIDsUsed map[uint16]struct{} dataChannelsOpened uint32 dataChannelsRequested uint32 dataChannelsAccepted uint32 @@ -66,10 +67,11 @@ type SCTPTransport struct { // meant to be used together with the basic WebRTC API. func (api *API) NewSCTPTransport(dtls *DTLSTransport) *SCTPTransport { res := &SCTPTransport{ - dtlsTransport: dtls, - state: SCTPTransportStateConnecting, - api: api, - log: api.settingEngine.LoggerFactory.NewLogger("ortc"), + dtlsTransport: dtls, + state: SCTPTransportStateConnecting, + api: api, + log: api.settingEngine.LoggerFactory.NewLogger("ortc"), + dataChannelIDsUsed: make(map[uint16]struct{}), } res.updateMessageSize() @@ -106,12 +108,12 @@ func (r *SCTPTransport) Start(SCTPCapabilities) error { if dtlsTransport == nil || dtlsTransport.conn == nil { return errSCTPTransportDTLS } - sctpAssociation, err := sctp.Client(sctp.Config{ NetConn: dtlsTransport.conn, MaxReceiveBufferSize: r.api.settingEngine.sctp.maxReceiveBufferSize, EnableZeroChecksum: r.api.settingEngine.sctp.enableZeroChecksum, LoggerFactory: r.api.settingEngine.LoggerFactory, + RTOMax: float64(r.api.settingEngine.sctp.rtoMax) / float64(time.Millisecond), }) if err != nil { return err @@ -151,10 +153,8 @@ func (r *SCTPTransport) Stop() error { if r.sctpAssociation == nil { return nil } - err := r.sctpAssociation.Close() - if err != nil { - return err - } + + r.sctpAssociation.Abort("") r.sctpAssociation = nil r.state = SCTPTransportStateClosed @@ -313,6 +313,13 @@ func (r *SCTPTransport) onDataChannel(dc *DataChannel) (done chan struct{}) { r.lock.Lock() r.dataChannels = append(r.dataChannels, dc) r.dataChannelsAccepted++ + if dc.ID() != nil { + r.dataChannelIDsUsed[*dc.ID()] = struct{}{} + } else { + // This cannot happen, the constructor for this datachannel in the caller + // takes a pointer to the id. + r.log.Errorf("accepted data channel with no ID") + } handler := r.onDataChannelHandler r.lock.Unlock() @@ -414,26 +421,17 @@ func (r *SCTPTransport) generateAndSetDataChannelID(dtlsRole DTLSRole, idOut **u id++ } - max := r.MaxChannels() + maxVal := r.MaxChannels() r.lock.Lock() defer r.lock.Unlock() - // Create map of ids so we can compare without double-looping each time. - idsMap := make(map[uint16]struct{}, len(r.dataChannels)) - for _, dc := range r.dataChannels { - if dc.ID() == nil { - continue - } - - idsMap[*dc.ID()] = struct{}{} - } - - for ; id < max-1; id += 2 { - if _, ok := idsMap[id]; ok { + for ; id < maxVal-1; id += 2 { + if _, ok := r.dataChannelIDsUsed[id]; ok { continue } *idOut = &id + r.dataChannelIDsUsed[id] = struct{}{} return nil } diff --git a/vendor/github.com/pion/webrtc/v3/sctptransport_js.go b/vendor/github.com/pion/webrtc/v4/sctptransport_js.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/sctptransport_js.go rename to vendor/github.com/pion/webrtc/v4/sctptransport_js.go diff --git a/vendor/github.com/pion/webrtc/v3/sctptransportstate.go b/vendor/github.com/pion/webrtc/v4/sctptransportstate.go similarity index 90% rename from vendor/github.com/pion/webrtc/v3/sctptransportstate.go rename to vendor/github.com/pion/webrtc/v4/sctptransportstate.go index 5dd51d6f5d..9deb73813e 100644 --- a/vendor/github.com/pion/webrtc/v3/sctptransportstate.go +++ b/vendor/github.com/pion/webrtc/v4/sctptransportstate.go @@ -7,10 +7,13 @@ package webrtc type SCTPTransportState int const ( + // SCTPTransportStateUnknown is the enum's zero-value + SCTPTransportStateUnknown SCTPTransportState = iota + // SCTPTransportStateConnecting indicates the SCTPTransport is in the // process of negotiating an association. This is the initial state of the // SCTPTransportState when an SCTPTransport is created. - SCTPTransportStateConnecting SCTPTransportState = iota + 1 + SCTPTransportStateConnecting // SCTPTransportStateConnected indicates the negotiation of an // association is completed. @@ -39,7 +42,7 @@ func newSCTPTransportState(raw string) SCTPTransportState { case sctpTransportStateClosedStr: return SCTPTransportStateClosed default: - return SCTPTransportState(Unknown) + return SCTPTransportStateUnknown } } diff --git a/vendor/github.com/pion/webrtc/v3/sdp.go b/vendor/github.com/pion/webrtc/v4/sdp.go similarity index 96% rename from vendor/github.com/pion/webrtc/v3/sdp.go rename to vendor/github.com/pion/webrtc/v4/sdp.go index 18f05e884e..3dd79b50a0 100644 --- a/vendor/github.com/pion/webrtc/v3/sdp.go +++ b/vendor/github.com/pion/webrtc/v4/sdp.go @@ -15,7 +15,7 @@ import ( "strings" "sync/atomic" - "github.com/pion/ice/v2" + "github.com/pion/ice/v4" "github.com/pion/logging" "github.com/pion/sdp/v3" ) @@ -85,7 +85,7 @@ func trackDetailsFromSDP(log logging.LeveledLogger, s *sdp.SessionDescription) ( tracksInMediaSection := []trackDetails{} rtxRepairFlows := map[uint64]uint64{} - // Plan B can have multiple tracks in a signle media section + // Plan B can have multiple tracks in a single media section streamID := "" trackID := "" @@ -374,6 +374,7 @@ func populateLocalCandidates(sessionDescription *SessionDescription, i *ICEGathe } } +// nolint: gocognit func addSenderSDP( mediaSection mediaSection, isPlanB bool, @@ -392,8 +393,23 @@ func addSenderSDP( sendParameters := sender.GetParameters() for _, encoding := range sendParameters.Encodings { + if encoding.RTX.SSRC != 0 { + media = media.WithValueAttribute("ssrc-group", fmt.Sprintf("FID %d %d", encoding.SSRC, encoding.RTX.SSRC)) + } + if encoding.FEC.SSRC != 0 { + media = media.WithValueAttribute("ssrc-group", fmt.Sprintf("FEC-FR %d %d", encoding.SSRC, encoding.FEC.SSRC)) + } + media = media.WithMediaSource(uint32(encoding.SSRC), track.StreamID() /* cname */, track.StreamID() /* streamLabel */, track.ID()) + if !isPlanB { + if encoding.RTX.SSRC != 0 { + media = media.WithMediaSource(uint32(encoding.RTX.SSRC), track.StreamID() /* cname */, track.StreamID() /* streamLabel */, track.ID()) + } + if encoding.FEC.SSRC != 0 { + media = media.WithMediaSource(uint32(encoding.FEC.SSRC), track.StreamID() /* cname */, track.StreamID() /* streamLabel */, track.ID()) + } + media = media.WithPropertyAttribute("msid:" + track.StreamID() + " " + track.ID()) } } @@ -552,7 +568,7 @@ type mediaSection struct { func bundleMatchFromRemote(matchBundleGroup *string) func(mid string) bool { if matchBundleGroup == nil { - return func(midValue string) bool { + return func(string) bool { return true } } @@ -696,11 +712,11 @@ func descriptionPossiblyPlanB(desc *SessionDescription) bool { func getPeerDirection(media *sdp.MediaDescription) RTPTransceiverDirection { for _, a := range media.Attributes { - if direction := NewRTPTransceiverDirection(a.Key); direction != RTPTransceiverDirection(Unknown) { + if direction := NewRTPTransceiverDirection(a.Key); direction != RTPTransceiverDirectionUnknown { return direction } } - return RTPTransceiverDirection(Unknown) + return RTPTransceiverDirectionUnknown } func extractFingerprint(desc *sdp.SessionDescription) (string, string, error) { diff --git a/vendor/github.com/pion/webrtc/v3/sdpsemantics.go b/vendor/github.com/pion/webrtc/v4/sdpsemantics.go similarity index 96% rename from vendor/github.com/pion/webrtc/v3/sdpsemantics.go rename to vendor/github.com/pion/webrtc/v4/sdpsemantics.go index 6d63350477..689b4e95bf 100644 --- a/vendor/github.com/pion/webrtc/v3/sdpsemantics.go +++ b/vendor/github.com/pion/webrtc/v4/sdpsemantics.go @@ -36,14 +36,12 @@ const ( func newSDPSemantics(raw string) SDPSemantics { switch raw { - case sdpSemanticsUnifiedPlan: - return SDPSemanticsUnifiedPlan case sdpSemanticsPlanB: return SDPSemanticsPlanB case sdpSemanticsUnifiedPlanWithFallback: return SDPSemanticsUnifiedPlanWithFallback default: - return SDPSemantics(Unknown) + return SDPSemanticsUnifiedPlan } } diff --git a/vendor/github.com/pion/webrtc/v3/sdptype.go b/vendor/github.com/pion/webrtc/v4/sdptype.go similarity index 95% rename from vendor/github.com/pion/webrtc/v3/sdptype.go rename to vendor/github.com/pion/webrtc/v4/sdptype.go index 0c6d1d4649..5aa3b98611 100644 --- a/vendor/github.com/pion/webrtc/v3/sdptype.go +++ b/vendor/github.com/pion/webrtc/v4/sdptype.go @@ -12,9 +12,11 @@ import ( type SDPType int const ( - // SDPTypeOffer indicates that a description MUST be treated as an SDP - // offer. - SDPTypeOffer SDPType = iota + 1 + // SDPTypeUnknown is the enum's zero-value + SDPTypeUnknown SDPType = iota + + // SDPTypeOffer indicates that a description MUST be treated as an SDP offer. + SDPTypeOffer // SDPTypePranswer indicates that a description MUST be treated as an // SDP answer, but not a final answer. A description used as an SDP @@ -56,7 +58,7 @@ func NewSDPType(raw string) SDPType { case sdpTypeRollbackStr: return SDPTypeRollback default: - return SDPType(Unknown) + return SDPTypeUnknown } } diff --git a/vendor/github.com/pion/webrtc/v3/sessiondescription.go b/vendor/github.com/pion/webrtc/v4/sessiondescription.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/sessiondescription.go rename to vendor/github.com/pion/webrtc/v4/sessiondescription.go diff --git a/vendor/github.com/pion/webrtc/v3/settingengine.go b/vendor/github.com/pion/webrtc/v4/settingengine.go similarity index 84% rename from vendor/github.com/pion/webrtc/v3/settingengine.go rename to vendor/github.com/pion/webrtc/v4/settingengine.go index 38dbe5b0d9..f3c70707c9 100644 --- a/vendor/github.com/pion/webrtc/v3/settingengine.go +++ b/vendor/github.com/pion/webrtc/v4/settingengine.go @@ -13,14 +13,14 @@ import ( "net" "time" - "github.com/pion/dtls/v2" - dtlsElliptic "github.com/pion/dtls/v2/pkg/crypto/elliptic" - "github.com/pion/ice/v2" + "github.com/pion/dtls/v3" + dtlsElliptic "github.com/pion/dtls/v3/pkg/crypto/elliptic" + "github.com/pion/dtls/v3/pkg/protocol/handshake" + "github.com/pion/ice/v4" "github.com/pion/logging" - "github.com/pion/stun" - "github.com/pion/transport/v2" - "github.com/pion/transport/v2/packetio" - "github.com/pion/transport/v2/vnet" + "github.com/pion/stun/v3" + "github.com/pion/transport/v3" + "github.com/pion/transport/v3/packetio" "golang.org/x/net/proxy" ) @@ -43,6 +43,7 @@ type SettingEngine struct { ICESrflxAcceptanceMinWait *time.Duration ICEPrflxAcceptanceMinWait *time.Duration ICERelayAcceptanceMinWait *time.Duration + ICESTUNGatherTimeout *time.Duration } candidates struct { ICELite bool @@ -63,20 +64,25 @@ type SettingEngine struct { SRTCP *uint } dtls struct { - insecureSkipHelloVerify bool - disableInsecureSkipVerify bool - retransmissionInterval time.Duration - ellipticCurves []dtlsElliptic.Curve - connectContextMaker func() (context.Context, func()) - extendedMasterSecret dtls.ExtendedMasterSecretType - clientAuth *dtls.ClientAuthType - clientCAs *x509.CertPool - rootCAs *x509.CertPool - keyLogWriter io.Writer + insecureSkipHelloVerify bool + disableInsecureSkipVerify bool + retransmissionInterval time.Duration + ellipticCurves []dtlsElliptic.Curve + connectContextMaker func() (context.Context, func()) + extendedMasterSecret dtls.ExtendedMasterSecretType + clientAuth *dtls.ClientAuthType + clientCAs *x509.CertPool + rootCAs *x509.CertPool + keyLogWriter io.Writer + customCipherSuites func() []dtls.CipherSuite + clientHelloMessageHook func(handshake.MessageClientHello) handshake.Message + serverHelloMessageHook func(handshake.MessageServerHello) handshake.Message + certificateRequestMessageHook func(handshake.MessageCertificateRequest) handshake.Message } sctp struct { maxReceiveBufferSize uint32 enableZeroChecksum bool + rtoMax time.Duration } sdpMediaLevelFingerprints bool answeringDTLSRole DTLSRole @@ -94,6 +100,7 @@ type SettingEngine struct { disableMediaEngineCopy bool srtpProtectionProfiles []dtls.SRTPProtectionProfile receiveMTU uint + iceMaxBindingRequests *uint16 } // getReceiveMTU returns the configured MTU. If SettingEngine's MTU is configured to 0 it returns the default @@ -157,6 +164,11 @@ func (e *SettingEngine) SetRelayAcceptanceMinWait(t time.Duration) { e.timeout.ICERelayAcceptanceMinWait = &t } +// SetSTUNGatherTimeout sets the ICESTUNGatherTimeout +func (e *SettingEngine) SetSTUNGatherTimeout(t time.Duration) { + e.timeout.ICESTUNGatherTimeout = &t +} + // SetEphemeralUDPPortRange limits the pool of ephemeral ports that // ICE UDP connections can allocate from. This affects both host candidates, // and the local address of server reflexive candidates. @@ -256,16 +268,6 @@ func (e *SettingEngine) SetAnsweringDTLSRole(role DTLSRole) error { return nil } -// SetVNet sets the VNet instance that is passed to pion/ice -// -// VNet is a virtual network layer for Pion, allowing users to simulate -// different topologies, latency, loss and jitter. This can be useful for -// learning WebRTC concepts or testing your application in a lab environment -// Deprecated: Please use SetNet() -func (e *SettingEngine) SetVNet(vnet *vnet.Net) { - e.SetNet(vnet) -} - // SetNet sets the Net instance that is passed to pion/ice // // Net is an network interface layer for Pion, allowing users to replace @@ -353,6 +355,12 @@ func (e *SettingEngine) SetICEProxyDialer(d proxy.Dialer) { e.iceProxyDialer = d } +// SetICEMaxBindingRequests sets the maximum amount of binding requests +// that can be sent on a candidate before it is considered invalid. +func (e *SettingEngine) SetICEMaxBindingRequests(d uint16) { + e.iceMaxBindingRequests = &d +} + // DisableActiveTCP disables using active TCP for ICE. Active TCP is enabled by default func (e *SettingEngine) DisableActiveTCP(isDisabled bool) { e.iceDisableActiveTCP = isDisabled @@ -438,13 +446,43 @@ func (e *SettingEngine) SetSCTPMaxReceiveBufferSize(maxReceiveBufferSize uint32) e.sctp.maxReceiveBufferSize = maxReceiveBufferSize } -// SetSCTPZeroChecksum enables the zero checksum feature in SCTP. +// EnableSCTPZeroChecksum controls the zero checksum feature in SCTP. // This removes the need to checksum every incoming/outgoing packet and will reduce // latency and CPU usage. This feature is not backwards compatible so is disabled by default func (e *SettingEngine) EnableSCTPZeroChecksum(isEnabled bool) { e.sctp.enableZeroChecksum = isEnabled } +// SetDTLSCustomerCipherSuites allows the user to specify a list of DTLS CipherSuites. +// This allow usage of Ciphers that are reserved for private usage. +func (e *SettingEngine) SetDTLSCustomerCipherSuites(customCipherSuites func() []dtls.CipherSuite) { + e.dtls.customCipherSuites = customCipherSuites +} + +// SetDTLSClientHelloMessageHook if not nil, is called when a DTLS Client Hello message is sent +// from a client. The returned handshake message replaces the original message. +func (e *SettingEngine) SetDTLSClientHelloMessageHook(hook func(handshake.MessageClientHello) handshake.Message) { + e.dtls.clientHelloMessageHook = hook +} + +// SetDTLSServerHelloMessageHook if not nil, is called when a DTLS Server Hello message is sent +// from a client. The returned handshake message replaces the original message. +func (e *SettingEngine) SetDTLSServerHelloMessageHook(hook func(handshake.MessageServerHello) handshake.Message) { + e.dtls.serverHelloMessageHook = hook +} + +// SetDTLSCertificateRequestMessageHook if not nil, is called when a DTLS Certificate Request message is sent +// from a client. The returned handshake message replaces the original message. +func (e *SettingEngine) SetDTLSCertificateRequestMessageHook(hook func(handshake.MessageCertificateRequest) handshake.Message) { + e.dtls.certificateRequestMessageHook = hook +} + +// SetSCTPRTOMax sets the maximum retransmission timeout. +// Leave this 0 for the default timeout. +func (e *SettingEngine) SetSCTPRTOMax(rtoMax time.Duration) { + e.sctp.rtoMax = rtoMax +} + // SetICEBindingRequestHandler sets a callback that is fired on a STUN BindingRequest // This allows users to do things like // - Log incoming Binding Requests for debugging diff --git a/vendor/github.com/pion/webrtc/v3/settingengine_js.go b/vendor/github.com/pion/webrtc/v4/settingengine_js.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/settingengine_js.go rename to vendor/github.com/pion/webrtc/v4/settingengine_js.go diff --git a/vendor/github.com/pion/webrtc/v3/signalingstate.go b/vendor/github.com/pion/webrtc/v4/signalingstate.go similarity index 96% rename from vendor/github.com/pion/webrtc/v3/signalingstate.go rename to vendor/github.com/pion/webrtc/v4/signalingstate.go index 42911c9af7..9d60afd260 100644 --- a/vendor/github.com/pion/webrtc/v3/signalingstate.go +++ b/vendor/github.com/pion/webrtc/v4/signalingstate.go @@ -7,7 +7,7 @@ import ( "fmt" "sync/atomic" - "github.com/pion/webrtc/v3/pkg/rtcerr" + "github.com/pion/webrtc/v4/pkg/rtcerr" ) type stateChangeOp int @@ -32,10 +32,13 @@ func (op stateChangeOp) String() string { type SignalingState int32 const ( + // SignalingStateUnknown is the enum's zero-value + SignalingStateUnknown SignalingState = iota + // SignalingStateStable indicates there is no offer/answer exchange in // progress. This is also the initial state, in which case the local and // remote descriptions are nil. - SignalingStateStable SignalingState = iota + 1 + SignalingStateStable // SignalingStateHaveLocalOffer indicates that a local description, of // type "offer", has been successfully applied. @@ -84,7 +87,7 @@ func newSignalingState(raw string) SignalingState { case signalingStateClosedStr: return SignalingStateClosed default: - return SignalingState(Unknown) + return SignalingStateUnknown } } diff --git a/vendor/github.com/pion/webrtc/v3/srtp_writer_future.go b/vendor/github.com/pion/webrtc/v4/srtp_writer_future.go similarity index 99% rename from vendor/github.com/pion/webrtc/v3/srtp_writer_future.go rename to vendor/github.com/pion/webrtc/v4/srtp_writer_future.go index 6855e8d309..fe090858b2 100644 --- a/vendor/github.com/pion/webrtc/v3/srtp_writer_future.go +++ b/vendor/github.com/pion/webrtc/v4/srtp_writer_future.go @@ -13,7 +13,7 @@ import ( "time" "github.com/pion/rtp" - "github.com/pion/srtp/v2" + "github.com/pion/srtp/v3" ) // srtpWriterFuture blocks Read/Write calls until diff --git a/vendor/github.com/pion/webrtc/v3/stats.go b/vendor/github.com/pion/webrtc/v4/stats.go similarity index 83% rename from vendor/github.com/pion/webrtc/v3/stats.go rename to vendor/github.com/pion/webrtc/v4/stats.go index a0b0795e11..7e4350449a 100644 --- a/vendor/github.com/pion/webrtc/v3/stats.go +++ b/vendor/github.com/pion/webrtc/v4/stats.go @@ -9,7 +9,7 @@ import ( "sync" "time" - "github.com/pion/ice/v2" + "github.com/pion/ice/v4" ) // A Stats object contains a set of statistics copies out of a monitored component @@ -275,6 +275,10 @@ func unmarshalCodecStats(b []byte) (CodecStats, error) { // InboundRTPStreamStats contains statistics for an inbound RTP stream that is // currently received with this PeerConnection object. type InboundRTPStreamStats struct { + // Mid represents a mid value of RTPTransceiver owning this stream, if that value is not + // null. Otherwise, this member is not present. + Mid string `json:"mid"` + // Timestamp is the timestamp associated with this object. Timestamp StatsTimestamp `json:"timestamp"` @@ -309,10 +313,92 @@ type InboundRTPStreamStats struct { // received by the sender. This metric is only valid for video and is sent by receiver. PLICount uint32 `json:"pliCount"` + // TotalProcessingDelay is the sum of the time, in seconds, each audio sample or video frame + // takes from the time the first RTP packet is received (reception timestamp) and to the time + // the corresponding sample or frame is decoded (decoded timestamp). At this point the audio + // sample or video frame is ready for playout by the MediaStreamTrack. Typically ready for + // playout here means after the audio sample or video frame is fully decoded by the decoder. + TotalProcessingDelay float64 `json:"totalProcessingDelay"` + // NACKCount counts the total number of Negative ACKnowledgement (NACK) packets // received by the sender and is sent by receiver. NACKCount uint32 `json:"nackCount"` + // JitterBufferDelay is the sum of the time, in seconds, each audio sample or a video frame + // takes from the time the first packet is received by the jitter buffer (ingest timestamp) + // to the time it exits the jitter buffer (emit timestamp). The average jitter buffer delay + // can be calculated by dividing the JitterBufferDelay with the JitterBufferEmittedCount. + JitterBufferDelay float64 `json:"jitterBufferDelay"` + + // JitterBufferTargetDelay is increased by the target jitter buffer delay every time a sample is emitted + // by the jitter buffer. The added target is the target delay, in seconds, at the time that + // the sample was emitted from the jitter buffer. To get the average target delay, + // divide by JitterBufferEmittedCount + JitterBufferTargetDelay float64 `json:"jitterBufferTargetDelay"` + + // JitterBufferEmittedCount is the total number of audio samples or video frames that + // have come out of the jitter buffer (increasing jitterBufferDelay). + JitterBufferEmittedCount uint64 `json:"jitterBufferEmittedCount"` + + // JitterBufferMinimumDelay works the same way as jitterBufferTargetDelay, except that + // it is not affected by external mechanisms that increase the jitter buffer target delay, + // such as jitterBufferTarget, AV sync, or any other mechanisms. This metric is purely + // based on the network characteristics such as jitter and packet loss, and can be seen + // as the minimum obtainable jitter buffer delay if no external factors would affect it. + // The metric is updated every time JitterBufferEmittedCount is updated. + JitterBufferMinimumDelay float64 `json:"jitterBufferMinimumDelay"` + + // TotalSamplesReceived is the total number of samples that have been received on + // this RTP stream. This includes concealedSamples. Does not exist for video. + TotalSamplesReceived uint64 `json:"totalSamplesReceived"` + + // ConcealedSamples is the total number of samples that are concealed samples. + // A concealed sample is a sample that was replaced with synthesized samples generated + // locally before being played out. Examples of samples that have to be concealed are + // samples from lost packets (reported in packetsLost) or samples from packets that + // arrive too late to be played out (reported in packetsDiscarded). Does not exist for video. + ConcealedSamples uint64 `json:"concealedSamples"` + + // SilentConcealedSamples is the total number of concealed samples inserted that + // are "silent". Playing out silent samples results in silence or comfort noise. + // This is a subset of concealedSamples. Does not exist for video. + SilentConcealedSamples uint64 `json:"silentConcealedSamples"` + + // ConcealmentEvents increases every time a concealed sample is synthesized after + // a non-concealed sample. That is, multiple consecutive concealed samples will increase + // the concealedSamples count multiple times but is a single concealment event. + // Does not exist for video. + ConcealmentEvents uint64 `json:"concealmentEvents"` + + // InsertedSamplesForDeceleration is increased by the difference between the number of + // samples received and the number of samples played out when playout is slowed down. + // If playout is slowed down by inserting samples, this will be the number of inserted samples. + // Does not exist for video. + InsertedSamplesForDeceleration uint64 `json:"insertedSamplesForDeceleration"` + + // RemovedSamplesForAcceleration is increased by the difference between the number of + // samples received and the number of samples played out when playout is sped up. If speedup + // is achieved by removing samples, this will be the count of samples removed. + // Does not exist for video. + RemovedSamplesForAcceleration uint64 `json:"removedSamplesForAcceleration"` + + // AudioLevel represents the audio level of the receiving track.. + // + // The value is a value between 0..1 (linear), where 1.0 represents 0 dBov, + // 0 represents silence, and 0.5 represents approximately 6 dBSPL change in + // the sound pressure level from 0 dBov. Does not exist for video. + AudioLevel float64 `json:"audioLevel"` + + // TotalAudioEnergy represents the audio energy of the receiving track. It is calculated + // by duration * Math.pow(energy/maxEnergy, 2) for each audio sample received (and thus + // counted by TotalSamplesReceived). Does not exist for video. + TotalAudioEnergy float64 `json:"totalAudioEnergy"` + + // TotalSamplesDuration represents the total duration in seconds of all samples that have been + // received (and thus counted by TotalSamplesReceived). Can be used with totalAudioEnergy to + // compute an average audio level over different intervals. Does not exist for video. + TotalSamplesDuration float64 `json:"totalSamplesDuration"` + // SLICount counts the total number of Slice Loss Indication (SLI) packets received // by the sender. This metric is only valid for video and is sent by receiver. SLICount uint32 `json:"sliCount"` @@ -321,6 +407,25 @@ type InboundRTPStreamStats struct { // in FramesDecoded for inbound stream stats, and in FramesEncoded for outbound stream stats. QPSum uint64 `json:"qpSum"` + // TotalDecodeTime is the total number of seconds that have been spent decoding the FramesDecoded + // frames of this stream. The average decode time can be calculated by dividing this value + // with FramesDecoded. The time it takes to decode one frame is the time passed between + // feeding the decoder a frame and the decoder returning decoded data for that frame. + TotalDecodeTime float64 `json:"totalDecodeTime"` + + // TotalInterFrameDelay is the sum of the interframe delays in seconds between consecutively + // rendered frames, recorded just after a frame has been rendered. The interframe delay variance + // be calculated from TotalInterFrameDelay, TotalSquaredInterFrameDelay, and FramesRendered according + // to the formula: (TotalSquaredInterFrameDelay - TotalInterFrameDelay^2 / FramesRendered) / FramesRendered. + // Does not exist for audio. + TotalInterFrameDelay float64 `json:"totalInterFrameDelay"` + + // TotalSquaredInterFrameDelay is the sum of the squared interframe delays in seconds + // between consecutively rendered frames, recorded just after a frame has been rendered. + // See TotalInterFrameDelay for details on how to calculate the interframe delay variance. + // Does not exist for audio. + TotalSquaredInterFrameDelay float64 `json:"totalSquaredInterFrameDelay"` + // PacketsReceived is the total number of RTP packets received for this SSRC. PacketsReceived uint32 `json:"packetsReceived"` @@ -383,11 +488,41 @@ type InboundRTPStreamStats struct { // i.e., frames that would be displayed if no frames are dropped. Only valid for video. FramesDecoded uint32 `json:"framesDecoded"` + // KeyFramesDecoded represents the total number of key frames, such as key frames in + // VP8 [RFC6386] or IDR-frames in H.264 [RFC6184], successfully decoded for this RTP + // media stream. This is a subset of FramesDecoded. FramesDecoded - KeyFramesDecoded + // gives you the number of delta frames decoded. Does not exist for audio. + KeyFramesDecoded uint32 `json:"keyFramesDecoded"` + + // FramesRendered represents the total number of frames that have been rendered. + // It is incremented just after a frame has been rendered. Does not exist for audio. + FramesRendered uint32 `json:"framesRendered"` + + // FramesDropped is the total number of frames dropped prior to decode or dropped + // because the frame missed its display deadline for this receiver's track. + // The measurement begins when the receiver is created and is a cumulative metric + // as defined in Appendix A (g) of [RFC7004]. Does not exist for audio. + FramesDropped uint32 `json:"framesDropped"` + + // FrameWidth represents the width of the last decoded frame. Before the first + // frame is decoded this member does not exist. Does not exist for audio. + FrameWidth uint32 `json:"frameWidth"` + + // FrameHeight represents the height of the last decoded frame. Before the first + // frame is decoded this member does not exist. Does not exist for audio. + FrameHeight uint32 `json:"frameHeight"` + // LastPacketReceivedTimestamp represents the timestamp at which the last packet was // received for this SSRC. This differs from Timestamp, which represents the time // at which the statistics were generated by the local endpoint. LastPacketReceivedTimestamp StatsTimestamp `json:"lastPacketReceivedTimestamp"` + // HeaderBytesReceived is the total number of RTP header and padding bytes received for this SSRC. + // This includes retransmissions. This does not include the size of transport layer headers such + // as IP or UDP. headerBytesReceived + bytesReceived equals the number of bytes received as + // payload over the transport. + HeaderBytesReceived uint64 `json:"headerBytesReceived"` + // AverageRTCPInterval is the average RTCP interval between two consecutive compound RTCP packets. // This is calculated by the sending endpoint when sending compound RTCP reports. // Compound packets must contain at least a RTCP RR or SR packet and an SDES packet @@ -398,9 +533,22 @@ type InboundRTPStreamStats struct { // This counter can also be incremented when receiving FEC packets in-band with media packets (e.g., with Opus). FECPacketsReceived uint32 `json:"fecPacketsReceived"` + // FECPacketsDiscarded is the total number of RTP FEC packets received for this SSRC where the + // error correction payload was discarded by the application. This may happen + // 1. if all the source packets protected by the FEC packet were received or already + // recovered by a separate FEC packet, or + // 2. if the FEC packet arrived late, i.e., outside the recovery window, and the + // lost RTP packets have already been skipped during playout. + // This is a subset of FECPacketsReceived. + FECPacketsDiscarded uint64 `json:"fecPacketsDiscarded"` + // BytesReceived is the total number of bytes received for this SSRC. BytesReceived uint64 `json:"bytesReceived"` + // FramesReceived represents the total number of complete frames received on this RTP stream. + // This metric is incremented when the complete frame is received. Does not exist for audio. + FramesReceived uint32 `json:"framesReceived"` + // PacketsFailedDecryption is the cumulative number of RTP packets that failed // to be decrypted. These packets are not counted by PacketsDiscarded. PacketsFailedDecryption uint32 `json:"packetsFailedDecryption"` @@ -453,6 +601,18 @@ const ( // OutboundRTPStreamStats contains statistics for an outbound RTP stream that is // currently sent with this PeerConnection object. type OutboundRTPStreamStats struct { + // Mid represents a mid value of RTPTransceiver owning this stream, if that value is not + // null. Otherwise, this member is not present. + Mid string `json:"mid"` + + // Rid only exists if a rid has been set for this RTP stream. + // Must not exist for audio. + Rid string `json:"rid"` + + // MediaSourceID is the identifier of the stats object representing the track currently + // attached to the sender of this stream, an RTCMediaSourceStats. + MediaSourceID string `json:"mediaSourceId"` + // Timestamp is the timestamp associated with this object. Timestamp StatsTimestamp `json:"timestamp"` @@ -479,6 +639,23 @@ type OutboundRTPStreamStats struct { // to produce the CodecStats associated with this RTP stream. CodecID string `json:"codecId"` + // HeaderBytesSent is the total number of RTP header and padding bytes sent for this SSRC. This does not + // include the size of transport layer headers such as IP or UDP. + // HeaderBytesSent + BytesSent equals the number of bytes sent as payload over the transport. + HeaderBytesSent uint64 `json:"headerBytesSent"` + + // RetransmittedPacketsSent is the total number of packets that were retransmitted for this SSRC. + // This is a subset of packetsSent. If RTX is not negotiated, retransmitted packets are sent + // over this ssrc. If RTX was negotiated, retransmitted packets are sent over a separate SSRC + // but is still accounted for here. + RetransmittedPacketsSent uint64 `json:"retransmittedPacketsSent"` + + // RetransmittedBytesSent is the total number of bytes that were retransmitted for this SSRC, + // only including payload bytes. This is a subset of bytesSent. If RTX is not negotiated, + // retransmitted bytes are sent over this ssrc. If RTX was negotiated, retransmitted bytes + // are sent over a separate SSRC but is still accounted for here. + RetransmittedBytesSent uint64 `json:"retransmittedBytesSent"` + // FIRCount counts the total number of Full Intra Request (FIR) packets received // by the sender. This metric is only valid for video and is sent by receiver. FIRCount uint32 `json:"firCount"` @@ -547,10 +724,47 @@ type OutboundRTPStreamStats struct { // It is measured in bits per second and the bitrate is calculated over a 1 second window. TargetBitrate float64 `json:"targetBitrate"` + // TotalEncodedBytesTarget is increased by the target frame size in bytes every time + // a frame has been encoded. The actual frame size may be bigger or smaller than this number. + // This value goes up every time framesEncoded goes up. + TotalEncodedBytesTarget uint64 `json:"totalEncodedBytesTarget"` + + // FrameWidth represents the width of the last encoded frame. The resolution of the + // encoded frame may be lower than the media source. Before the first frame is encoded + // this member does not exist. Does not exist for audio. + FrameWidth uint32 `json:"frameWidth"` + + // FrameHeight represents the height of the last encoded frame. The resolution of the + // encoded frame may be lower than the media source. Before the first frame is encoded + // this member does not exist. Does not exist for audio. + FrameHeight uint32 `json:"frameHeight"` + + // FramesPerSecond is the number of encoded frames during the last second. This may be + // lower than the media source frame rate. Does not exist for audio. + FramesPerSecond float64 `json:"framesPerSecond"` + + // FramesSent represents the total number of frames sent on this RTP stream. Does not exist for audio. + FramesSent uint32 `json:"framesSent"` + + // HugeFramesSent represents the total number of huge frames sent by this RTP stream. + // Huge frames, by definition, are frames that have an encoded size at least 2.5 times + // the average size of the frames. The average size of the frames is defined as the + // target bitrate per second divided by the target FPS at the time the frame was encoded. + // These are usually complex to encode frames with a lot of changes in the picture. + // This can be used to estimate, e.g slide changes in the streamed presentation. + // Does not exist for audio. + HugeFramesSent uint32 `json:"hugeFramesSent"` + // FramesEncoded represents the total number of frames successfully encoded for this RTP media stream. // Only valid for video. FramesEncoded uint32 `json:"framesEncoded"` + // KeyFramesEncoded represents the total number of key frames, such as key frames in VP8 [RFC6386] or + // IDR-frames in H.264 [RFC6184], successfully encoded for this RTP media stream. This is a subset of + // FramesEncoded. FramesEncoded - KeyFramesEncoded gives you the number of delta frames encoded. + // Does not exist for audio. + KeyFramesEncoded uint32 `json:"keyFramesEncoded"` + // TotalEncodeTime is the total number of seconds that has been spent encoding the // framesEncoded frames of this stream. The average encode time can be calculated by // dividing this value with FramesEncoded. The time it takes to encode one frame is the @@ -558,6 +772,12 @@ type OutboundRTPStreamStats struct { // for that frame. This does not include any additional time it may take to packetize the resulting data. TotalEncodeTime float64 `json:"totalEncodeTime"` + // TotalPacketSendDelay is the total number of seconds that packets have spent buffered + // locally before being transmitted onto the network. The time is measured from when + // a packet is emitted from the RTP packetizer until it is handed over to the OS network socket. + // This measurement is added to totalPacketSendDelay when packetsSent is incremented. + TotalPacketSendDelay float64 `json:"totalPacketSendDelay"` + // AverageRTCPInterval is the average RTCP interval between two consecutive compound RTCP // packets. This is calculated by the sending endpoint when sending compound RTCP reports. // Compound packets must contain at least a RTCP RR or SR packet and an SDES packet with the CNAME item. @@ -572,9 +792,20 @@ type OutboundRTPStreamStats struct { // for all QualityLimitationReason types, including "none". Only valid for video. QualityLimitationDurations map[string]float64 `json:"qualityLimitationDurations"` + // QualityLimitationResolutionChanges is the number of times that the resolution has changed + // because we are quality limited (qualityLimitationReason has a value other than "none"). + // The counter is initially zero and increases when the resolution goes up or down. + // For example, if a 720p track is sent as 480p for some time and then recovers to 720p, + // qualityLimitationResolutionChanges will have the value 2. Does not exist for audio. + QualityLimitationResolutionChanges uint32 `json:"qualityLimitationResolutionChanges"` + // PerDSCPPacketsSent is the total number of packets sent for this SSRC, per DSCP. // DSCPs are identified as decimal integers in string form. PerDSCPPacketsSent map[string]uint32 `json:"perDscpPacketsSent"` + + // Active indicates whether this RTP stream is configured to be sent or disabled. Note that an + // active stream can still not be sending, e.g. when being limited by network conditions. + Active bool `json:"active"` } func (s OutboundRTPStreamStats) statsMarker() {} @@ -692,8 +923,20 @@ type RemoteInboundRTPStreamStats struct { // RTCP timestamps in the RTCP Receiver Report (RR) and measured in seconds. RoundTripTime float64 `json:"roundTripTime"` + // TotalRoundTripTime represents the cumulative sum of all round trip time measurements + // in seconds since the beginning of the session. The individual round trip time is calculated + // based on the RTCP timestamps in the RTCP Receiver Report (RR) [RFC3550], hence requires + // a DLSR value other than 0. The average round trip time can be computed from + // TotalRoundTripTime by dividing it by RoundTripTimeMeasurements. + TotalRoundTripTime float64 `json:"totalRoundTripTime"` + // FractionLost is the fraction packet loss reported for this SSRC. FractionLost float64 `json:"fractionLost"` + + // RoundTripTimeMeasurements represents the total number of RTCP RR blocks received for this SSRC + // that contain a valid round trip time. This counter will not increment if the RoundTripTime can + // not be calculated because no RTCP Receiver Report with a DLSR value other than 0 has been received. + RoundTripTimeMeasurements uint64 `json:"roundTripTimeMeasurements"` } func (s RemoteInboundRTPStreamStats) statsMarker() {} @@ -791,6 +1034,28 @@ type RemoteOutboundRTPStreamStats struct { // Sender Report (SR) packet, which reflects the remote endpoint's clock. // That clock may not be synchronized with the local clock. RemoteTimestamp StatsTimestamp `json:"remoteTimestamp"` + + // ReportsSent represents the total number of RTCP Sender Report (SR) blocks sent for this SSRC. + ReportsSent uint64 `json:"reportsSent"` + + // RoundTripTime is estimated round trip time for this SSRC based on the latest + // RTCP Sender Report (SR) that contains a DLRR report block as defined in [RFC3611]. + // The Calculation of the round trip time is defined in section 4.5. of [RFC3611]. + // Does not exist if the latest SR does not contain the DLRR report block, or if the last RR timestamp + // in the DLRR report block is zero, or if the delay since last RR value in the DLRR report block is zero. + RoundTripTime float64 `json:"roundTripTime"` + + // TotalRoundTripTime represents the cumulative sum of all round trip time measurements in seconds + // since the beginning of the session. The individual round trip time is calculated based on the DLRR + // report block in the RTCP Sender Report (SR) [RFC3611]. This counter will not increment if the + // RoundTripTime can not be calculated. The average round trip time can be computed from + // TotalRoundTripTime by dividing it by RoundTripTimeMeasurements. + TotalRoundTripTime float64 `json:"totalRoundTripTime"` + + // RoundTripTimeMeasurements represents the total number of RTCP Sender Report (SR) blocks + // received for this SSRC that contain a DLRR report block that can derive a valid round trip time + // according to [RFC3611]. This counter will not increment if the RoundTripTime can not be calculated. + RoundTripTimeMeasurements uint64 `json:"roundTripTimeMeasurements"` } func (s RemoteOutboundRTPStreamStats) statsMarker() {} @@ -1636,12 +1901,16 @@ type TransportStats struct { RTCPTransportStatsID string `json:"rtcpTransportStatsId"` // ICERole is set to the current value of the "role" attribute of the underlying - // DTLSTransport's "transport". + // DTLSTransport's "iceTransport". ICERole ICERole `json:"iceRole"` // DTLSState is set to the current value of the "state" attribute of the underlying DTLSTransport. DTLSState DTLSTransportState `json:"dtlsState"` + // ICEState is set to the current value of the "state" attribute of the underlying + // RTCIceTransport's "state". + ICEState ICETransportState `json:"iceState"` + // SelectedCandidatePairID is a unique identifier that is associated to the object // that was inspected to produce the ICECandidatePairStats associated with this transport. SelectedCandidatePairID string `json:"selectedCandidatePairId"` @@ -1897,6 +2166,19 @@ type ICECandidatePairStats struct { // ConsentExpiredTimestamp represents the timestamp at which the latest valid // STUN binding response expired. ConsentExpiredTimestamp StatsTimestamp `json:"consentExpiredTimestamp"` + + // PacketsDiscardedOnSend retpresents the total number of packets for this candidate pair + // that have been discarded due to socket errors, i.e. a socket error occurred + // when handing the packets to the socket. This might happen due to various reasons, + // including full buffer or no available memory. + PacketsDiscardedOnSend uint32 `json:"packetsDiscardedOnSend"` + + // BytesDiscardedOnSend represents the total number of bytes for this candidate pair + // that have been discarded due to socket errors, i.e. a socket error occurred + // when handing the packets containing the bytes to the socket. This might happen due + // to various reasons, including full buffer or no available memory. + // Calculated as defined in [RFC3550] section 6.4.1. + BytesDiscardedOnSend uint32 `json:"bytesDiscardedOnSend"` } func (s ICECandidatePairStats) statsMarker() {} @@ -1940,7 +2222,7 @@ type ICECandidateStats struct { // // DEPRECATED. Although it may still work in some browsers, the networkType property was deprecated for // preserving privacy. - NetworkType NetworkType `json:"networkType,omitempty"` + NetworkType string `json:"networkType,omitempty"` // IP is the IP address of the candidate, allowing for IPv4 addresses and // IPv6 addresses, but fully qualified domain names (FQDNs) are not allowed. diff --git a/vendor/github.com/pion/webrtc/v3/stats_go.go b/vendor/github.com/pion/webrtc/v4/stats_go.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/stats_go.go rename to vendor/github.com/pion/webrtc/v4/stats_go.go diff --git a/vendor/github.com/pion/webrtc/v3/track_local.go b/vendor/github.com/pion/webrtc/v4/track_local.go similarity index 79% rename from vendor/github.com/pion/webrtc/v3/track_local.go rename to vendor/github.com/pion/webrtc/v4/track_local.go index 21131c8111..86a6b7f837 100644 --- a/vendor/github.com/pion/webrtc/v3/track_local.go +++ b/vendor/github.com/pion/webrtc/v4/track_local.go @@ -21,17 +21,22 @@ type TrackLocalWriter interface { // in Interceptors. type TrackLocalContext interface { // CodecParameters returns the negotiated RTPCodecParameters. These are the codecs supported by both - // PeerConnections and the SSRC/PayloadTypes + // PeerConnections and the PayloadTypes CodecParameters() []RTPCodecParameters // HeaderExtensions returns the negotiated RTPHeaderExtensionParameters. These are the header extensions supported by - // both PeerConnections and the SSRC/PayloadTypes + // both PeerConnections and the URI/IDs HeaderExtensions() []RTPHeaderExtensionParameter - // SSRC requires the negotiated SSRC of this track - // This track may have multiple if RTX is enabled + // SSRC returns the negotiated SSRC of this track SSRC() SSRC + // SSRCRetransmission returns the negotiated SSRC used to send retransmissions for this track + SSRCRetransmission() SSRC + + // SSRCForwardErrorCorrection returns the negotiated SSRC to send forward error correction for this track + SSRCForwardErrorCorrection() SSRC + // WriteStream returns the WriteStream for this TrackLocal. The implementer writes the outbound // media packets to it WriteStream() TrackLocalWriter @@ -44,11 +49,11 @@ type TrackLocalContext interface { } type baseTrackLocalContext struct { - id string - params RTPParameters - ssrc SSRC - writeStream TrackLocalWriter - rtcpInterceptor interceptor.RTCPReader + id string + params RTPParameters + ssrc, ssrcRTX, ssrcFEC SSRC + writeStream TrackLocalWriter + rtcpInterceptor interceptor.RTCPReader } // CodecParameters returns the negotiated RTPCodecParameters. These are the codecs supported by both @@ -64,11 +69,20 @@ func (t *baseTrackLocalContext) HeaderExtensions() []RTPHeaderExtensionParameter } // SSRC requires the negotiated SSRC of this track -// This track may have multiple if RTX is enabled func (t *baseTrackLocalContext) SSRC() SSRC { return t.ssrc } +// SSRCRetransmission returns the negotiated SSRC used to send retransmissions for this track +func (t *baseTrackLocalContext) SSRCRetransmission() SSRC { + return t.ssrcRTX +} + +// SSRCForwardErrorCorrection returns the negotiated SSRC to send forward error correction for this track +func (t *baseTrackLocalContext) SSRCForwardErrorCorrection() SSRC { + return t.ssrcFEC +} + // WriteStream returns the WriteStream for this TrackLocal. The implementer writes the outbound // media packets to it func (t *baseTrackLocalContext) WriteStream() TrackLocalWriter { diff --git a/vendor/github.com/pion/webrtc/v3/track_local_static.go b/vendor/github.com/pion/webrtc/v4/track_local_static.go similarity index 93% rename from vendor/github.com/pion/webrtc/v3/track_local_static.go rename to vendor/github.com/pion/webrtc/v4/track_local_static.go index 1c06feba94..d4ca1ed5c0 100644 --- a/vendor/github.com/pion/webrtc/v3/track_local_static.go +++ b/vendor/github.com/pion/webrtc/v4/track_local_static.go @@ -11,18 +11,18 @@ import ( "sync" "github.com/pion/rtp" - "github.com/pion/webrtc/v3/internal/util" - "github.com/pion/webrtc/v3/pkg/media" + "github.com/pion/webrtc/v4/internal/util" + "github.com/pion/webrtc/v4/pkg/media" ) // trackBinding is a single bind for a Track // Bind can be called multiple times, this stores the // result for a single bind call so that it can be used when writing type trackBinding struct { - id string - ssrc SSRC - payloadType PayloadType - writeStream TrackLocalWriter + id string + ssrc, ssrcRTX, ssrcFEC SSRC + payloadType, payloadTypeRTX PayloadType + writeStream TrackLocalWriter } // TrackLocalStaticRTP is a TrackLocal that has a pre-set codec and accepts RTP Packets. @@ -59,7 +59,7 @@ func WithRTPStreamID(rid string) func(*TrackLocalStaticRTP) { // Bind is called by the PeerConnection after negotiation is complete // This asserts that the code requested is supported by the remote peer. -// If so it setups all the state (SSRC and PayloadType) to have a call +// If so it sets up all the state (SSRC and PayloadType) to have a call func (s *TrackLocalStaticRTP) Bind(t TrackLocalContext) (RTPCodecParameters, error) { s.mu.Lock() defer s.mu.Unlock() @@ -67,11 +67,15 @@ func (s *TrackLocalStaticRTP) Bind(t TrackLocalContext) (RTPCodecParameters, err parameters := RTPCodecParameters{RTPCodecCapability: s.codec} if codec, matchType := codecParametersFuzzySearch(parameters, t.CodecParameters()); matchType != codecMatchNone { s.bindings = append(s.bindings, trackBinding{ - ssrc: t.SSRC(), - payloadType: codec.PayloadType, - writeStream: t.WriteStream(), - id: t.ID(), + ssrc: t.SSRC(), + ssrcRTX: t.SSRCRetransmission(), + ssrcFEC: t.SSRCForwardErrorCorrection(), + payloadType: codec.PayloadType, + payloadTypeRTX: findRTXPayloadType(codec.PayloadType, t.CodecParameters()), + writeStream: t.WriteStream(), + id: t.ID(), }) + return codec, nil } diff --git a/vendor/github.com/pion/webrtc/v3/track_remote.go b/vendor/github.com/pion/webrtc/v4/track_remote.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/track_remote.go rename to vendor/github.com/pion/webrtc/v4/track_remote.go diff --git a/vendor/github.com/pion/webrtc/v3/webrtc.go b/vendor/github.com/pion/webrtc/v4/webrtc.go similarity index 100% rename from vendor/github.com/pion/webrtc/v3/webrtc.go rename to vendor/github.com/pion/webrtc/v4/webrtc.go diff --git a/vendor/github.com/pion/webrtc/v4/yarn.lock b/vendor/github.com/pion/webrtc/v4/yarn.lock new file mode 100644 index 0000000000..809d55604c --- /dev/null +++ b/vendor/github.com/pion/webrtc/v4/yarn.lock @@ -0,0 +1,377 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + +# SPDX-FileCopyrightText: 2023 The Pion community +# SPDX-License-Identifier: MIT + +"@roamhq/wrtc-darwin-arm64@0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@roamhq/wrtc-darwin-arm64/-/wrtc-darwin-arm64-0.8.0.tgz#15057e6b8f57e4d1b7008a9d848b6f2036adbb24" + integrity sha512-OtV2KWO7zOG3L8TF3KCt9aucynVCD/ww2xeXXgg+FLkya3ca0uzehN8EQJ3BL4tkInksbFJ2ssyu9cehfJ3ZuA== + +"@roamhq/wrtc-darwin-x64@0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@roamhq/wrtc-darwin-x64/-/wrtc-darwin-x64-0.8.0.tgz#e09137b5a7edf2c2412bc63f1da1893dcaa211fd" + integrity sha512-VY7Vzt/SDDDCpW//h8GW9bOZrOr8gWXPZVD9473ypl4jyBIoO57yyLbHzd1G0vBUkS6szsHlQCz1WwpI30YL+g== + +"@roamhq/wrtc-linux-arm64@0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@roamhq/wrtc-linux-arm64/-/wrtc-linux-arm64-0.8.1.tgz#9a5f3297de44fcec86713d0baefa0594658ab71e" + integrity sha512-FBJLLazlWkGQUXaokC/rTbrUQbb0CNFYry52fZGstufrGLTWu+g4HcwXdVvxh1tnVtVMvkQGk+mlOL52sCxw0A== + +"@roamhq/wrtc-linux-x64@0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@roamhq/wrtc-linux-x64/-/wrtc-linux-x64-0.8.1.tgz#3c5b60ca6cc6ebf5c2389d852f4a101135031da2" + integrity sha512-I9oWG7b4uvWO1IOR/aF34n+ID6TKVuSs0jd19h5KdhfRtw7FFh9xxuwN9rONPxLVa6fS0q+MCZgAf8Scz89L8Q== + +"@roamhq/wrtc-win32-x64@0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@roamhq/wrtc-win32-x64/-/wrtc-win32-x64-0.8.0.tgz#582e2478df48201d5757b60dcd4b4dcc40a054b7" + integrity sha512-R2fxl41BLWPiP4eaTHGLzbbVvRjx1mV/OsgINCvawO7Hwz5Zx9I45+Fhrw3hd4n5amIeSG9VIF7Kz8eeTFXTGQ== + +"@roamhq/wrtc@^0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@roamhq/wrtc/-/wrtc-0.8.0.tgz#03c8c64c3b6a1e6e8965ec6496fa7e97571ae04b" + integrity sha512-C0V/nqc4/2xzORI5qa4mIeN/8UO3ywN1kInrJ9u6GljFx0D18JMUJEqe8yYHa61RrEeoWN3PKdW++k8TocSx/A== + optionalDependencies: + "@roamhq/wrtc-darwin-arm64" "0.8.0" + "@roamhq/wrtc-darwin-x64" "0.8.0" + "@roamhq/wrtc-linux-arm64" "0.8.1" + "@roamhq/wrtc-linux-x64" "0.8.1" + "@roamhq/wrtc-win32-x64" "0.8.0" + domexception "^4.0.0" + +ajv@^6.5.5: + version "6.12.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd" + integrity sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.0.tgz#a17b3a8ea811060e74d47d306122400ad4497ae2" + integrity sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA== + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +domexception@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-4.0.0.tgz#4ad1be56ccadc86fc76d033353999a8037d03673" + integrity sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw== + dependencies: + webidl-conversions "^7.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fast-deep-equal@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" + integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + dependencies: + ajv "^6.5.5" + har-schema "^2.0.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +mime-db@1.44.0: + version "1.44.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" + integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== + +mime-types@^2.1.12, mime-types@~2.1.19: + version "2.1.27" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" + integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== + dependencies: + mime-db "1.44.0" + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +psl@^1.1.28: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +request@2.88.2: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +safe-buffer@^5.0.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +webidl-conversions@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" + integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== diff --git a/vendor/github.com/urfave/cli/v2/help.go b/vendor/github.com/urfave/cli/v2/help.go index 874be941c0..f1b9e7f18f 100644 --- a/vendor/github.com/urfave/cli/v2/help.go +++ b/vendor/github.com/urfave/cli/v2/help.go @@ -150,7 +150,7 @@ func printCommandSuggestions(commands []*Command, writer io.Writer) { if command.Hidden { continue } - if strings.HasSuffix(os.Getenv("SHELL"), "zsh") { + if strings.HasSuffix(os.Getenv("0"), "zsh") { for _, name := range command.Names() { _, _ = fmt.Fprintf(writer, "%s:%s\n", name, command.Usage) } diff --git a/vendor/modules.txt b/vendor/modules.txt index 886d943873..b0f9d03c21 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -61,7 +61,7 @@ github.com/CortexFoundation/robot/backend # github.com/CortexFoundation/statik v0.0.0-20210315012922-8bb8a7b5dc66 ## explicit; go 1.16 github.com/CortexFoundation/statik -# github.com/CortexFoundation/torrentfs v1.0.69-0.20241010111105-9de7a9574507 +# github.com/CortexFoundation/torrentfs v1.0.69-0.20241014112616-2c6fbb777c44 ## explicit; go 1.23.0 github.com/CortexFoundation/torrentfs github.com/CortexFoundation/torrentfs/backend @@ -154,7 +154,7 @@ github.com/anacrolix/stm/stmutil # github.com/anacrolix/sync v0.5.3 ## explicit; go 1.13 github.com/anacrolix/sync -# github.com/anacrolix/torrent v1.57.2-0.20241007003033-f21937e55137 +# github.com/anacrolix/torrent v1.57.2-0.20241014100415-05ab0cad4774 ## explicit; go 1.23 github.com/anacrolix/torrent github.com/anacrolix/torrent/analysis @@ -552,7 +552,7 @@ github.com/garslo/gogen # github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 ## explicit github.com/gballet/go-libpcsclite -# github.com/getsentry/sentry-go v0.29.0 +# github.com/getsentry/sentry-go v0.29.1 ## explicit; go 1.18 github.com/getsentry/sentry-go github.com/getsentry/sentry-go/internal/debug @@ -835,33 +835,37 @@ github.com/peterh/liner # github.com/pion/datachannel v1.5.9 ## explicit; go 1.19 github.com/pion/datachannel -# github.com/pion/dtls/v2 v2.2.12 -## explicit; go 1.13 -github.com/pion/dtls/v2 -github.com/pion/dtls/v2/internal/ciphersuite -github.com/pion/dtls/v2/internal/ciphersuite/types -github.com/pion/dtls/v2/internal/closer -github.com/pion/dtls/v2/internal/util -github.com/pion/dtls/v2/pkg/crypto/ccm -github.com/pion/dtls/v2/pkg/crypto/ciphersuite -github.com/pion/dtls/v2/pkg/crypto/clientcertificate -github.com/pion/dtls/v2/pkg/crypto/elliptic -github.com/pion/dtls/v2/pkg/crypto/fingerprint -github.com/pion/dtls/v2/pkg/crypto/hash -github.com/pion/dtls/v2/pkg/crypto/prf -github.com/pion/dtls/v2/pkg/crypto/signature -github.com/pion/dtls/v2/pkg/crypto/signaturehash -github.com/pion/dtls/v2/pkg/protocol -github.com/pion/dtls/v2/pkg/protocol/alert -github.com/pion/dtls/v2/pkg/protocol/extension -github.com/pion/dtls/v2/pkg/protocol/handshake -github.com/pion/dtls/v2/pkg/protocol/recordlayer -# github.com/pion/ice/v2 v2.3.36 -## explicit; go 1.13 -github.com/pion/ice/v2 -github.com/pion/ice/v2/internal/atomic -github.com/pion/ice/v2/internal/fakenet -github.com/pion/ice/v2/internal/stun +# github.com/pion/dtls/v3 v3.0.3 +## explicit; go 1.20 +github.com/pion/dtls/v3 +github.com/pion/dtls/v3/internal/ciphersuite +github.com/pion/dtls/v3/internal/ciphersuite/types +github.com/pion/dtls/v3/internal/closer +github.com/pion/dtls/v3/internal/net +github.com/pion/dtls/v3/internal/net/udp +github.com/pion/dtls/v3/internal/util +github.com/pion/dtls/v3/pkg/crypto/ccm +github.com/pion/dtls/v3/pkg/crypto/ciphersuite +github.com/pion/dtls/v3/pkg/crypto/clientcertificate +github.com/pion/dtls/v3/pkg/crypto/elliptic +github.com/pion/dtls/v3/pkg/crypto/fingerprint +github.com/pion/dtls/v3/pkg/crypto/hash +github.com/pion/dtls/v3/pkg/crypto/prf +github.com/pion/dtls/v3/pkg/crypto/signature +github.com/pion/dtls/v3/pkg/crypto/signaturehash +github.com/pion/dtls/v3/pkg/net +github.com/pion/dtls/v3/pkg/protocol +github.com/pion/dtls/v3/pkg/protocol/alert +github.com/pion/dtls/v3/pkg/protocol/extension +github.com/pion/dtls/v3/pkg/protocol/handshake +github.com/pion/dtls/v3/pkg/protocol/recordlayer +# github.com/pion/ice/v4 v4.0.2 +## explicit; go 1.20 +github.com/pion/ice/v4 +github.com/pion/ice/v4/internal/atomic +github.com/pion/ice/v4/internal/fakenet +github.com/pion/ice/v4/internal/stun +github.com/pion/ice/v4/internal/taskloop # github.com/pion/interceptor v0.1.37 ## explicit; go 1.20 github.com/pion/interceptor @@ -869,13 +873,14 @@ github.com/pion/interceptor/internal/ntp github.com/pion/interceptor/internal/sequencenumber github.com/pion/interceptor/pkg/nack github.com/pion/interceptor/pkg/report +github.com/pion/interceptor/pkg/rfc8888 github.com/pion/interceptor/pkg/twcc # github.com/pion/logging v0.2.2 ## explicit; go 1.12 github.com/pion/logging -# github.com/pion/mdns v0.0.12 +# github.com/pion/mdns/v2 v2.0.7 ## explicit; go 1.19 -github.com/pion/mdns +github.com/pion/mdns/v2 # github.com/pion/randutil v0.1.0 ## explicit; go 1.14 github.com/pion/randutil @@ -894,40 +899,39 @@ github.com/pion/sctp # github.com/pion/sdp/v3 v3.0.9 ## explicit; go 1.13 github.com/pion/sdp/v3 -# github.com/pion/srtp/v2 v2.0.20 -## explicit; go 1.14 -github.com/pion/srtp/v2 -# github.com/pion/stun v0.6.2-0.20230901070932-d1f1ac894921 -## explicit; go 1.12 -github.com/pion/stun -github.com/pion/stun/internal/hmac -# github.com/pion/transport/v2 v2.2.10 -## explicit; go 1.12 -github.com/pion/transport/v2 -github.com/pion/transport/v2/connctx -github.com/pion/transport/v2/deadline -github.com/pion/transport/v2/packetio -github.com/pion/transport/v2/replaydetector -github.com/pion/transport/v2/stdnet -github.com/pion/transport/v2/udp -github.com/pion/transport/v2/utils/xor -github.com/pion/transport/v2/vnet -# github.com/pion/turn/v2 v2.1.6 -## explicit; go 1.13 -github.com/pion/turn/v2 -github.com/pion/turn/v2/internal/allocation -github.com/pion/turn/v2/internal/client -github.com/pion/turn/v2/internal/ipnet -github.com/pion/turn/v2/internal/proto -github.com/pion/turn/v2/internal/server -# github.com/pion/webrtc/v3 v3.3.4 -## explicit; go 1.17 -github.com/pion/webrtc/v3 -github.com/pion/webrtc/v3/internal/fmtp -github.com/pion/webrtc/v3/internal/mux -github.com/pion/webrtc/v3/internal/util -github.com/pion/webrtc/v3/pkg/media -github.com/pion/webrtc/v3/pkg/rtcerr +# github.com/pion/srtp/v3 v3.0.4 +## explicit; go 1.20 +github.com/pion/srtp/v3 +# github.com/pion/stun/v3 v3.0.0 +## explicit; go 1.19 +github.com/pion/stun/v3 +github.com/pion/stun/v3/internal/hmac +# github.com/pion/transport/v3 v3.0.7 +## explicit; go 1.19 +github.com/pion/transport/v3 +github.com/pion/transport/v3/deadline +github.com/pion/transport/v3/netctx +github.com/pion/transport/v3/packetio +github.com/pion/transport/v3/replaydetector +github.com/pion/transport/v3/stdnet +github.com/pion/transport/v3/utils/xor +github.com/pion/transport/v3/vnet +# github.com/pion/turn/v4 v4.0.0 +## explicit; go 1.19 +github.com/pion/turn/v4 +github.com/pion/turn/v4/internal/allocation +github.com/pion/turn/v4/internal/client +github.com/pion/turn/v4/internal/ipnet +github.com/pion/turn/v4/internal/proto +github.com/pion/turn/v4/internal/server +# github.com/pion/webrtc/v4 v4.0.0 +## explicit; go 1.20 +github.com/pion/webrtc/v4 +github.com/pion/webrtc/v4/internal/fmtp +github.com/pion/webrtc/v4/internal/mux +github.com/pion/webrtc/v4/internal/util +github.com/pion/webrtc/v4/pkg/media +github.com/pion/webrtc/v4/pkg/rtcerr # github.com/pkg/errors v0.9.1 ## explicit github.com/pkg/errors @@ -1034,7 +1038,7 @@ github.com/ucwong/filecache # github.com/ucwong/go-ttlmap v1.0.2-0.20221020173635-331e7ddde2bb ## explicit; go 1.19 github.com/ucwong/go-ttlmap -# github.com/ucwong/golang-kv v1.0.24-0.20241010105424-84c909d0d763 +# github.com/ucwong/golang-kv v1.0.24-0.20241013181450-613f8dd1b92b ## explicit; go 1.22.0 github.com/ucwong/golang-kv github.com/ucwong/golang-kv/badger @@ -1046,7 +1050,7 @@ github.com/ucwong/golang-kv/pebble # github.com/ucwong/shard v1.0.1-0.20240327124306-59a521744cae ## explicit; go 1.20 github.com/ucwong/shard -# github.com/urfave/cli/v2 v2.27.4 +# github.com/urfave/cli/v2 v2.27.5 ## explicit; go 1.18 github.com/urfave/cli/v2 # github.com/wlynxg/anet v0.0.5