@@ -135,7 +135,8 @@ Port::Port(rtc::Thread* thread,
135135 rtc::Network* network,
136136 const rtc::IPAddress& ip,
137137 const std::string& username_fragment,
138- const std::string& password)
138+ const std::string& password,
139+ const std::string& uproxy_transform)
139140 : thread_(thread),
140141 factory_ (factory),
141142 send_retransmit_count_attribute_(false ),
@@ -147,6 +148,8 @@ Port::Port(rtc::Thread* thread,
147148 generation_(0 ),
148149 ice_username_fragment_(username_fragment),
149150 password_(password),
151+ uproxy_transform_(uproxy_transform),
152+ transform_key_(0 ),
150153 timeout_delay_(kPortTimeoutDelay ),
151154 enable_port_packets_(false ),
152155 ice_role_(ICEROLE_UNKNOWN),
@@ -164,7 +167,8 @@ Port::Port(rtc::Thread* thread,
164167 uint16_t min_port,
165168 uint16_t max_port,
166169 const std::string& username_fragment,
167- const std::string& password)
170+ const std::string& password,
171+ const std::string& uproxy_transform)
168172 : thread_(thread),
169173 factory_(factory),
170174 type_(type),
@@ -177,6 +181,8 @@ Port::Port(rtc::Thread* thread,
177181 generation_(0 ),
178182 ice_username_fragment_(username_fragment),
179183 password_(password),
184+ uproxy_transform_(uproxy_transform),
185+ transform_key_(0 ),
180186 timeout_delay_(kPortTimeoutDelay ),
181187 enable_port_packets_(false ),
182188 ice_role_(ICEROLE_UNKNOWN),
@@ -196,6 +202,11 @@ void Port::Construct() {
196202 ice_username_fragment_ = rtc::CreateRandomString (ICE_UFRAG_LENGTH);
197203 password_ = rtc::CreateRandomString (ICE_PWD_LENGTH);
198204 }
205+ if (!uproxy_transform_.empty ()) {
206+ int space_point = uproxy_transform_.find (" " );
207+ transform_name_ = uproxy_transform_.substr (0 , space_point);
208+ transform_key_ = atoi (uproxy_transform_.substr (space_point + 1 ).c_str ());
209+ }
199210 network_->SignalInactive .connect (this , &Port::OnNetworkInactive);
200211 // TODO(honghaiz): Make it configurable from user setting.
201212 network_cost_ =
@@ -276,19 +287,20 @@ void Port::AddConnection(Connection* conn) {
276287}
277288
278289void Port::OnReadPacket (
279- const char * data , size_t size, const rtc::SocketAddress& addr,
290+ const char * raw_data , size_t size, const rtc::SocketAddress& addr,
280291 ProtocolType proto) {
292+ std::vector<char > data = ApplyTransform (raw_data, size, false );
281293 // If the user has enabled port packets, just hand this over.
282294 if (enable_port_packets_) {
283- SignalReadPacket (this , data, size, addr);
295+ SignalReadPacket (this , data. data (), data. size () , addr);
284296 return ;
285297 }
286298
287299 // If this is an authenticated STUN request, then signal unknown address and
288300 // send back a proper binding response.
289301 rtc::scoped_ptr<IceMessage> msg;
290302 std::string remote_username;
291- if (!GetStunMessage (data, size, addr, msg.accept (), &remote_username)) {
303+ if (!GetStunMessage (data. data (), data. size () , addr, msg.accept (), &remote_username)) {
292304 LOG_J (LS_ERROR, this ) << " Received non-STUN packet from unknown address ("
293305 << addr.ToSensitiveString () << " )" ;
294306 } else if (!msg) {
@@ -426,6 +438,18 @@ bool Port::GetStunMessage(const char* data, size_t size,
426438 return true ;
427439}
428440
441+ std::vector<char > Port::ApplyTransform (const void * data, size_t size, bool forward) const {
442+ const char * input_bytes = reinterpret_cast <const char *>(data);
443+ std::vector<char > output (size);
444+ if (transform_name_ == " caesar" ) {
445+ int shift = forward ? transform_key_ : -transform_key_;
446+ for (size_t i = 0 ; i < size; ++i) {
447+ output[i] = input_bytes[i] + shift;
448+ }
449+ }
450+ return output;
451+ }
452+
429453bool Port::IsCompatibleAddress (const rtc::SocketAddress& addr) {
430454 int family = ip ().family ();
431455 // We use single-stack sockets, so families must match.
@@ -575,7 +599,10 @@ void Port::SendBindingResponse(StunMessage* request,
575599 rtc::ByteBuffer buf;
576600 response.Write (&buf);
577601 rtc::PacketOptions options (DefaultDscpValue ());
578- auto err = SendTo (buf.Data (), buf.Length (), addr, options, false );
602+
603+ std::vector<char > data = ApplyTransform (buf.Data (), buf.Length (), true );
604+
605+ auto err = SendTo (data.data (), data.size (), addr, options, false );
579606 if (err < 0 ) {
580607 LOG_J (LS_ERROR, this )
581608 << " Failed to send STUN ping response"
@@ -623,7 +650,10 @@ void Port::SendBindingErrorResponse(StunMessage* request,
623650 rtc::ByteBuffer buf;
624651 response.Write (&buf);
625652 rtc::PacketOptions options (DefaultDscpValue ());
626- SendTo (buf.Data (), buf.Length (), addr, options, false );
653+
654+ std::vector<char > data = ApplyTransform (buf.Data (), buf.Length (), true );
655+
656+ SendTo (data.data (), data.size (), addr, options, false );
627657 LOG_J (LS_INFO, this ) << " Sending STUN binding error: reason=" << reason
628658 << " to " << addr.ToSensitiveString ();
629659}
@@ -885,11 +915,12 @@ void Connection::set_use_candidate_attr(bool enable) {
885915 use_candidate_attr_ = enable;
886916}
887917
888- void Connection::OnSendStunPacket (const void * data , size_t size,
918+ void Connection::OnSendStunPacket (const void * raw_data , size_t size,
889919 StunRequest* req) {
920+ std::vector<char > data = port_->ApplyTransform (raw_data, size, true );
890921 rtc::PacketOptions options (port_->DefaultDscpValue ());
891922 auto err = port_->SendTo (
892- data, size, remote_candidate_.address (), options, false );
923+ data. data (), data. size () , remote_candidate_.address (), options, false );
893924 if (err < 0 ) {
894925 LOG_J (LS_WARNING, this ) << " Failed to send STUN ping "
895926 << " err=" << err
@@ -898,17 +929,18 @@ void Connection::OnSendStunPacket(const void* data, size_t size,
898929}
899930
900931void Connection::OnReadPacket (
901- const char * data , size_t size, const rtc::PacketTime& packet_time) {
932+ const char * raw_data , size_t size, const rtc::PacketTime& packet_time) {
902933 rtc::scoped_ptr<IceMessage> msg;
903934 std::string remote_ufrag;
904935 const rtc::SocketAddress& addr (remote_candidate_.address ());
905- if (!port_->GetStunMessage (data, size, addr, msg.accept (), &remote_ufrag)) {
936+ std::vector<char > data = port_->ApplyTransform (raw_data, size, false );
937+ if (!port_->GetStunMessage (data.data (), data.size (), addr, msg.accept (), &remote_ufrag)) {
906938 // The packet did not parse as a valid STUN message
907939 // This is a data packet, pass it along.
908940 set_receiving (true );
909941 last_data_received_ = rtc::Time ();
910942 recv_rate_tracker_.AddSamples (size);
911- SignalReadPacket (this , data, size, packet_time);
943+ SignalReadPacket (this , data. data (), data. size () , packet_time);
912944
913945 // If timed out sending writability checks, start up again
914946 if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT)) {
@@ -951,7 +983,7 @@ void Connection::OnReadPacket(
951983 case STUN_BINDING_RESPONSE:
952984 case STUN_BINDING_ERROR_RESPONSE:
953985 if (msg->ValidateMessageIntegrity (
954- data, size, remote_candidate ().password ())) {
986+ data. data (), data. size () , remote_candidate ().password ())) {
955987 requests_.CheckResponse (msg.get ());
956988 }
957989 // Otherwise silently discard the response message.
@@ -1430,14 +1462,16 @@ ProxyConnection::ProxyConnection(Port* port,
14301462 const Candidate& remote_candidate)
14311463 : Connection(port, index, remote_candidate) {}
14321464
1433- int ProxyConnection::Send (const void * data , size_t size,
1465+ int ProxyConnection::Send (const void * raw_data , size_t size,
14341466 const rtc::PacketOptions& options) {
1467+ std::vector<char > data = port_->ApplyTransform (raw_data, size, true );
1468+
14351469 if (write_state_ == STATE_WRITE_INIT || write_state_ == STATE_WRITE_TIMEOUT) {
14361470 error_ = EWOULDBLOCK;
14371471 return SOCKET_ERROR;
14381472 }
14391473 sent_packets_total_++;
1440- int sent = port_->SendTo (data, size, remote_candidate_.address (),
1474+ int sent = port_->SendTo (data. data (), data. size () , remote_candidate_.address (),
14411475 options, true );
14421476 if (sent <= 0 ) {
14431477 ASSERT (sent < 0 );
0 commit comments