/src/mozilla-central/media/mtransport/transportlayerice.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
5 | | * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | // Original author: ekr@rtfm.com |
8 | | |
9 | | // Some of this code is cut-and-pasted from nICEr. Copyright is: |
10 | | |
11 | | /* |
12 | | Copyright (c) 2007, Adobe Systems, Incorporated |
13 | | All rights reserved. |
14 | | |
15 | | Redistribution and use in source and binary forms, with or without |
16 | | modification, are permitted provided that the following conditions are |
17 | | met: |
18 | | |
19 | | * Redistributions of source code must retain the above copyright |
20 | | notice, this list of conditions and the following disclaimer. |
21 | | |
22 | | * Redistributions in binary form must reproduce the above copyright |
23 | | notice, this list of conditions and the following disclaimer in the |
24 | | documentation and/or other materials provided with the distribution. |
25 | | |
26 | | * Neither the name of Adobe Systems, Network Resonance nor the names of its |
27 | | contributors may be used to endorse or promote products derived from |
28 | | this software without specific prior written permission. |
29 | | |
30 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
31 | | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
32 | | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
33 | | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
34 | | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
35 | | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
36 | | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
37 | | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
38 | | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
39 | | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
40 | | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
41 | | */ |
42 | | |
43 | | |
44 | | #include <string> |
45 | | #include <vector> |
46 | | |
47 | | #include "nsCOMPtr.h" |
48 | | #include "nsComponentManagerUtils.h" |
49 | | #include "nsError.h" |
50 | | #include "nsIEventTarget.h" |
51 | | #include "nsNetCID.h" |
52 | | #include "nsComponentManagerUtils.h" |
53 | | #include "nsServiceManagerUtils.h" |
54 | | |
55 | | // nICEr includes |
56 | | extern "C" { |
57 | | #include "nr_api.h" |
58 | | #include "registry.h" |
59 | | #include "async_timer.h" |
60 | | #include "ice_util.h" |
61 | | #include "transport_addr.h" |
62 | | #include "nr_crypto.h" |
63 | | #include "nr_socket.h" |
64 | | #include "nr_socket_local.h" |
65 | | #include "stun_client_ctx.h" |
66 | | #include "stun_server_ctx.h" |
67 | | #include "ice_ctx.h" |
68 | | #include "ice_candidate.h" |
69 | | #include "ice_handler.h" |
70 | | } |
71 | | |
72 | | // Local includes |
73 | | #include "logging.h" |
74 | | #include "nricectx.h" |
75 | | #include "nricemediastream.h" |
76 | | #include "transportflow.h" |
77 | | #include "transportlayerice.h" |
78 | | |
79 | | namespace mozilla { |
80 | | |
81 | | #ifdef ERROR |
82 | | #undef ERROR |
83 | | #endif |
84 | | |
85 | | MOZ_MTLOG_MODULE("mtransport") |
86 | | |
87 | | TransportLayerIce::TransportLayerIce() |
88 | | : stream_(nullptr), component_(0) |
89 | 0 | { |
90 | 0 | // setup happens later |
91 | 0 | } |
92 | | |
93 | 0 | TransportLayerIce::~TransportLayerIce() { |
94 | 0 | // No need to do anything here, since we use smart pointers |
95 | 0 | } |
96 | | |
97 | | void TransportLayerIce::SetParameters(RefPtr<NrIceMediaStream> stream, |
98 | 0 | int component) { |
99 | 0 | // Stream could be null in the case of some badly written js that causes |
100 | 0 | // us to be in an ICE restart case, but not have valid streams due to |
101 | 0 | // not calling PeerConnectionMedia::EnsureTransports if |
102 | 0 | // PeerConnectionImpl::SetSignalingState_m thinks the conditions were |
103 | 0 | // not correct. We also solved a case where an incoming answer was |
104 | 0 | // incorrectly beginning an ICE restart when the offer did not indicate one. |
105 | 0 | if (!stream) { |
106 | 0 | MOZ_ASSERT(false); |
107 | 0 | return; |
108 | 0 | } |
109 | 0 |
|
110 | 0 | stream_ = stream; |
111 | 0 | component_ = component; |
112 | 0 |
|
113 | 0 | PostSetup(); |
114 | 0 | } |
115 | | |
116 | 0 | void TransportLayerIce::PostSetup() { |
117 | 0 | stream_->SignalReady.connect(this, &TransportLayerIce::IceReady); |
118 | 0 | stream_->SignalFailed.connect(this, &TransportLayerIce::IceFailed); |
119 | 0 | stream_->SignalPacketReceived.connect(this, |
120 | 0 | &TransportLayerIce::IcePacketReceived); |
121 | 0 | if (stream_->state() == NrIceMediaStream::ICE_OPEN) { |
122 | 0 | TL_SET_STATE(TS_OPEN); |
123 | 0 | } |
124 | 0 | } |
125 | | |
126 | 0 | TransportResult TransportLayerIce::SendPacket(MediaPacket& packet) { |
127 | 0 | CheckThread(); |
128 | 0 | nsresult res = stream_->SendPacket(component_, |
129 | 0 | packet.data(), |
130 | 0 | packet.len()); |
131 | 0 |
|
132 | 0 | if (!NS_SUCCEEDED(res)) { |
133 | 0 | return (res == NS_BASE_STREAM_WOULD_BLOCK) ? |
134 | 0 | TE_WOULDBLOCK : TE_ERROR; |
135 | 0 | } |
136 | 0 |
|
137 | 0 | MOZ_MTLOG(ML_DEBUG, LAYER_INFO << " SendPacket(" << packet.len() << ") succeeded"); |
138 | 0 |
|
139 | 0 | return packet.len(); |
140 | 0 | } |
141 | | |
142 | | |
143 | | void TransportLayerIce::IceCandidate(NrIceMediaStream *stream, |
144 | 0 | const std::string&) { |
145 | 0 | // NO-OP for now |
146 | 0 | } |
147 | | |
148 | 0 | void TransportLayerIce::IceReady(NrIceMediaStream *stream) { |
149 | 0 | CheckThread(); |
150 | 0 | // only handle the current stream (not the old stream during restart) |
151 | 0 | if (stream != stream_) { |
152 | 0 | return; |
153 | 0 | } |
154 | 0 | MOZ_MTLOG(ML_INFO, LAYER_INFO << "ICE Ready(" << stream->name() << "," |
155 | 0 | << component_ << ")"); |
156 | 0 | TL_SET_STATE(TS_OPEN); |
157 | 0 | } |
158 | | |
159 | 0 | void TransportLayerIce::IceFailed(NrIceMediaStream *stream) { |
160 | 0 | CheckThread(); |
161 | 0 | // only handle the current stream (not the old stream during restart) |
162 | 0 | if (stream != stream_) { |
163 | 0 | return; |
164 | 0 | } |
165 | 0 | MOZ_MTLOG(ML_INFO, LAYER_INFO << "ICE Failed(" << stream->name() << "," |
166 | 0 | << component_ << ")"); |
167 | 0 | TL_SET_STATE(TS_ERROR); |
168 | 0 | } |
169 | | |
170 | | void TransportLayerIce::IcePacketReceived(NrIceMediaStream *stream, int component, |
171 | 0 | const unsigned char *data, int len) { |
172 | 0 | CheckThread(); |
173 | 0 | // We get packets for both components, so ignore the ones that aren't |
174 | 0 | // for us. |
175 | 0 | if (component_ != component) |
176 | 0 | return; |
177 | 0 | |
178 | 0 | MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "PacketReceived(" << stream->name() << "," |
179 | 0 | << component << "," << len << ")"); |
180 | 0 | // Might be useful to allow MediaPacket to borrow a buffer (ie; not take |
181 | 0 | // ownership, but copy it if the MediaPacket is moved). This could be a |
182 | 0 | // footgun though with MediaPackets that end up on the heap. |
183 | 0 | MediaPacket packet; |
184 | 0 | packet.Copy(data, len); |
185 | 0 | SignalPacketReceived(this, packet); |
186 | 0 | } |
187 | | |
188 | | } // close namespace |