Reland "Move JsepTransport from p2p/base to pc/."

This is a reland of 4770fd935ac92400487bddd3b755753572e6d692
Original change's description:
> Move JsepTransport from p2p/base to pc/.
> 
> The JsepTransport class is moved to pc/ and the utility methods and
> enums are moved to where they are used.
> 
> With JsepTransport moved to pc/, JsepTransport can depend on objects in
> pc/ including RtpTranport, SrtpTransport etc.
> 
> Forked from https://webrtc-review.googlesource.com/c/src/+/31762/7
> 
> Bug: webrtc:8636
> Change-Id: I4e8569fe3012946e87deb280f6139f0fd98de34d
> Reviewed-on: https://webrtc-review.googlesource.com/33701
> Reviewed-by: Steve Anton <steveanton@webrtc.org>
> Reviewed-by: Peter Thatcher <pthatcher@webrtc.org>
> Commit-Queue: Taylor Brandstetter <deadbeef@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#21333}

Bug: webrtc:8636
Change-Id: Ibce42be898b96dd8e0266b595611d2ffc86581a8
Reviewed-on: https://webrtc-review.googlesource.com/34586
Commit-Queue: Taylor Brandstetter <deadbeef@webrtc.org>
Reviewed-by: Peter Thatcher <pthatcher@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21371}
diff --git a/p2p/BUILD.gn b/p2p/BUILD.gn
index cd54b7d..f2173f4 100644
--- a/p2p/BUILD.gn
+++ b/p2p/BUILD.gn
@@ -33,7 +33,6 @@
     "base/dtlstransportinternal.h",
     "base/icetransportinternal.cc",
     "base/icetransportinternal.h",
-    "base/jseptransport.cc",
     "base/jseptransport.h",
     "base/p2pconstants.cc",
     "base/p2pconstants.h",
@@ -156,7 +155,6 @@
     sources = [
       "base/asyncstuntcpsocket_unittest.cc",
       "base/dtlstransport_unittest.cc",
-      "base/jseptransport_unittest.cc",
       "base/p2ptransportchannel_unittest.cc",
       "base/packetlossestimator_unittest.cc",
       "base/port_unittest.cc",
diff --git a/p2p/base/dtlstransportinternal.h b/p2p/base/dtlstransportinternal.h
index b08868f..2acbda6 100644
--- a/p2p/base/dtlstransportinternal.h
+++ b/p2p/base/dtlstransportinternal.h
@@ -16,13 +16,25 @@
 #include <vector>
 
 #include "p2p/base/icetransportinternal.h"
-#include "p2p/base/jseptransport.h"
 #include "p2p/base/packettransportinternal.h"
 #include "rtc_base/sslstreamadapter.h"
 #include "rtc_base/stringencode.h"
 
 namespace cricket {
 
+enum DtlsTransportState {
+  // Haven't started negotiating.
+  DTLS_TRANSPORT_NEW = 0,
+  // Have started negotiating.
+  DTLS_TRANSPORT_CONNECTING,
+  // Negotiated, and has a secure connection.
+  DTLS_TRANSPORT_CONNECTED,
+  // Transport is closed.
+  DTLS_TRANSPORT_CLOSED,
+  // Failed due to some error in the handshake process.
+  DTLS_TRANSPORT_FAILED,
+};
+
 enum PacketFlags {
   PF_NORMAL = 0x00,       // A normal packet.
   PF_SRTP_BYPASS = 0x01,  // An encrypted SRTP packet; bypass any additional
diff --git a/p2p/base/icetransportinternal.cc b/p2p/base/icetransportinternal.cc
index d5fa989..e4e56fe 100644
--- a/p2p/base/icetransportinternal.cc
+++ b/p2p/base/icetransportinternal.cc
@@ -12,6 +12,30 @@
 
 namespace cricket {
 
+IceConfig::IceConfig() = default;
+
+IceConfig::IceConfig(int receiving_timeout_ms,
+                     int backup_connection_ping_interval,
+                     ContinualGatheringPolicy gathering_policy,
+                     bool prioritize_most_likely_candidate_pairs,
+                     int stable_writable_connection_ping_interval_ms,
+                     bool presume_writable_when_fully_relayed,
+                     int regather_on_failed_networks_interval_ms,
+                     int receiving_switching_delay_ms)
+    : receiving_timeout(receiving_timeout_ms),
+      backup_connection_ping_interval(backup_connection_ping_interval),
+      continual_gathering_policy(gathering_policy),
+      prioritize_most_likely_candidate_pairs(
+          prioritize_most_likely_candidate_pairs),
+      stable_writable_connection_ping_interval(
+          stable_writable_connection_ping_interval_ms),
+      presume_writable_when_fully_relayed(presume_writable_when_fully_relayed),
+      regather_on_failed_networks_interval(
+          regather_on_failed_networks_interval_ms),
+      receiving_switching_delay(receiving_switching_delay_ms) {}
+
+IceConfig::~IceConfig() = default;
+
 IceTransportInternal::IceTransportInternal() = default;
 
 IceTransportInternal::~IceTransportInternal() = default;
diff --git a/p2p/base/icetransportinternal.h b/p2p/base/icetransportinternal.h
index 0a71162..787f66e 100644
--- a/p2p/base/icetransportinternal.h
+++ b/p2p/base/icetransportinternal.h
@@ -12,11 +12,12 @@
 #define P2P_BASE_ICETRANSPORTINTERNAL_H_
 
 #include <string>
+#include <vector>
 
 #include "api/candidate.h"
 #include "p2p/base/candidatepairinterface.h"
-#include "p2p/base/jseptransport.h"
 #include "p2p/base/packettransportinternal.h"
+#include "p2p/base/port.h"
 #include "p2p/base/transportdescription.h"
 #include "rtc_base/stringencode.h"
 
@@ -26,6 +27,106 @@
 
 namespace cricket {
 
+typedef std::vector<Candidate> Candidates;
+
+enum IceConnectionState {
+  kIceConnectionConnecting = 0,
+  kIceConnectionFailed,
+  kIceConnectionConnected,  // Writable, but still checking one or more
+                            // connections
+  kIceConnectionCompleted,
+};
+
+// TODO(deadbeef): Unify with PeerConnectionInterface::IceConnectionState
+// once /talk/ and /webrtc/ are combined, and also switch to ENUM_NAME naming
+// style.
+enum IceGatheringState {
+  kIceGatheringNew = 0,
+  kIceGatheringGathering,
+  kIceGatheringComplete,
+};
+
+enum ContinualGatheringPolicy {
+  // All port allocator sessions will stop after a writable connection is found.
+  GATHER_ONCE = 0,
+  // The most recent port allocator session will keep on running.
+  GATHER_CONTINUALLY,
+  // The most recent port allocator session will keep on running, and it will
+  // try to recover connectivity if the channel becomes disconnected.
+  GATHER_CONTINUALLY_AND_RECOVER,
+};
+
+// ICE Nomination mode.
+enum class NominationMode {
+  REGULAR,         // Nominate once per ICE restart (Not implemented yet).
+  AGGRESSIVE,      // Nominate every connection except that it will behave as if
+                   // REGULAR when the remote is an ICE-LITE endpoint.
+  SEMI_AGGRESSIVE  // Our current implementation of the nomination algorithm.
+                   // The details are described in P2PTransportChannel.
+};
+
+// Information about ICE configuration.
+// TODO(deadbeef): Use rtc::Optional to represent unset values, instead of
+// -1.
+struct IceConfig {
+  // The ICE connection receiving timeout value in milliseconds.
+  int receiving_timeout = -1;
+  // Time interval in milliseconds to ping a backup connection when the ICE
+  // channel is strongly connected.
+  int backup_connection_ping_interval = -1;
+
+  ContinualGatheringPolicy continual_gathering_policy = GATHER_ONCE;
+
+  bool gather_continually() const {
+    return continual_gathering_policy == GATHER_CONTINUALLY ||
+           continual_gathering_policy == GATHER_CONTINUALLY_AND_RECOVER;
+  }
+
+  // Whether we should prioritize Relay/Relay candidate when nothing
+  // is writable yet.
+  bool prioritize_most_likely_candidate_pairs = false;
+
+  // Writable connections are pinged at a slower rate once stablized.
+  int stable_writable_connection_ping_interval = -1;
+
+  // If set to true, this means the ICE transport should presume TURN-to-TURN
+  // candidate pairs will succeed, even before a binding response is received.
+  bool presume_writable_when_fully_relayed = false;
+
+  // Interval to check on all networks and to perform ICE regathering on any
+  // active network having no connection on it.
+  rtc::Optional<int> regather_on_failed_networks_interval;
+
+  // Interval to perform ICE regathering on all networks
+  // The delay in milliseconds is sampled from the uniform distribution [a, b]
+  rtc::Optional<rtc::IntervalRange> regather_all_networks_interval_range;
+
+  // The time period in which we will not switch the selected connection
+  // when a new connection becomes receiving but the selected connection is not
+  // in case that the selected connection may become receiving soon.
+  rtc::Optional<int> receiving_switching_delay;
+
+  // TODO(honghaiz): Change the default to regular nomination.
+  // Default nomination mode if the remote does not support renomination.
+  NominationMode default_nomination_mode = NominationMode::SEMI_AGGRESSIVE;
+
+  // ICE checks (STUN pings) will not be sent at higher rate (lower interval)
+  // than this, no matter what other settings there are.
+  // Measure in milliseconds.
+  rtc::Optional<int> ice_check_min_interval;
+
+  IceConfig();
+  IceConfig(int receiving_timeout_ms,
+            int backup_connection_ping_interval,
+            ContinualGatheringPolicy gathering_policy,
+            bool prioritize_most_likely_candidate_pairs,
+            int stable_writable_connection_ping_interval_ms,
+            bool presume_writable_when_fully_relayed,
+            int regather_on_failed_networks_interval_ms,
+            int receiving_switching_delay_ms);
+  ~IceConfig();
+};
+
 // TODO(zhihuang): Replace this with
 // PeerConnectionInterface::IceConnectionState.
 enum class IceTransportState {
diff --git a/p2p/base/jseptransport.h b/p2p/base/jseptransport.h
index f045556..3af3634 100644
--- a/p2p/base/jseptransport.h
+++ b/p2p/base/jseptransport.h
@@ -11,373 +11,35 @@
 #ifndef P2P_BASE_JSEPTRANSPORT_H_
 #define P2P_BASE_JSEPTRANSPORT_H_
 
-#include <map>
-#include <memory>
-#include <string>
 #include <vector>
 
+// TODO(deadbeef): This file used to be a dumping ground of various enums,
+// structs, etc., which have now moved to their own files. Delete this file
+// once no one is depending on it, and they start including the more specific
+// file(s) instead.
+
 #include "api/candidate.h"
-#include "api/jsep.h"
-#include "api/optional.h"
+
+// DTLS enums/structs.
+#include "p2p/base/dtlstransport.h"
+#include "p2p/base/dtlstransportinternal.h"
+
+// ICE enums/structs.
+#include "p2p/base/icetransportinternal.h"
+
+// Various constants.
 #include "p2p/base/p2pconstants.h"
+
+// ConnectionInfo, among many other things.
+#include "p2p/base/port.h"
+
+// SDP structures
 #include "p2p/base/sessiondescription.h"
 #include "p2p/base/transportinfo.h"
-#include "rtc_base/constructormagic.h"
-#include "rtc_base/messagequeue.h"
-#include "rtc_base/rtccertificate.h"
-#include "rtc_base/sigslot.h"
-#include "rtc_base/sslstreamadapter.h"
 
+// Legacy typedef.
 namespace cricket {
-
-class DtlsTransportInternal;
-enum class IceCandidatePairState;
-
 typedef std::vector<Candidate> Candidates;
-
-// TODO(deadbeef): Move all of these enums, POD types and utility methods to
-// another header file.
-
-// TODO(deadbeef): Unify with PeerConnectionInterface::IceConnectionState
-// once /talk/ and /webrtc/ are combined, and also switch to ENUM_NAME naming
-// style.
-enum IceConnectionState {
-  kIceConnectionConnecting = 0,
-  kIceConnectionFailed,
-  kIceConnectionConnected,  // Writable, but still checking one or more
-                            // connections
-  kIceConnectionCompleted,
-};
-
-enum DtlsTransportState {
-  // Haven't started negotiating.
-  DTLS_TRANSPORT_NEW = 0,
-  // Have started negotiating.
-  DTLS_TRANSPORT_CONNECTING,
-  // Negotiated, and has a secure connection.
-  DTLS_TRANSPORT_CONNECTED,
-  // Transport is closed.
-  DTLS_TRANSPORT_CLOSED,
-  // Failed due to some error in the handshake process.
-  DTLS_TRANSPORT_FAILED,
-};
-
-// TODO(deadbeef): Unify with PeerConnectionInterface::IceConnectionState
-// once /talk/ and /webrtc/ are combined, and also switch to ENUM_NAME naming
-// style.
-enum IceGatheringState {
-  kIceGatheringNew = 0,
-  kIceGatheringGathering,
-  kIceGatheringComplete,
-};
-
-enum ContinualGatheringPolicy {
-  // All port allocator sessions will stop after a writable connection is found.
-  GATHER_ONCE = 0,
-  // The most recent port allocator session will keep on running.
-  GATHER_CONTINUALLY,
-  // The most recent port allocator session will keep on running, and it will
-  // try to recover connectivity if the channel becomes disconnected.
-  GATHER_CONTINUALLY_AND_RECOVER,
-};
-
-// Stats that we can return about the connections for a transport channel.
-// TODO(hta): Rename to ConnectionStats
-struct ConnectionInfo {
-  ConnectionInfo();
-  ConnectionInfo(const ConnectionInfo&);
-  ~ConnectionInfo();
-
-  bool best_connection;      // Is this the best connection we have?
-  bool writable;             // Has this connection received a STUN response?
-  bool receiving;            // Has this connection received anything?
-  bool timeout;              // Has this connection timed out?
-  bool new_connection;       // Is this a newly created connection?
-  size_t rtt;                // The STUN RTT for this connection.
-  size_t sent_total_bytes;   // Total bytes sent on this connection.
-  size_t sent_bytes_second;  // Bps over the last measurement interval.
-  size_t sent_discarded_packets;  // Number of outgoing packets discarded due to
-                                  // socket errors.
-  size_t sent_total_packets;  // Number of total outgoing packets attempted for
-                              // sending.
-  size_t sent_ping_requests_total;  // Number of STUN ping request sent.
-  size_t sent_ping_requests_before_first_response;  // Number of STUN ping
-  // sent before receiving the first response.
-  size_t sent_ping_responses;  // Number of STUN ping response sent.
-
-  size_t recv_total_bytes;     // Total bytes received on this connection.
-  size_t recv_bytes_second;    // Bps over the last measurement interval.
-  size_t recv_ping_requests;   // Number of STUN ping request received.
-  size_t recv_ping_responses;  // Number of STUN ping response received.
-  Candidate local_candidate;   // The local candidate for this connection.
-  Candidate remote_candidate;  // The remote candidate for this connection.
-  void* key;                   // A static value that identifies this conn.
-  // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-state
-  IceCandidatePairState state;
-  // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-priority
-  uint64_t priority;
-  // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-nominated
-  bool nominated;
-  // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-totalroundtriptime
-  uint64_t total_round_trip_time_ms;
-  // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-currentroundtriptime
-  rtc::Optional<uint32_t> current_round_trip_time_ms;
-};
-
-// Information about all the connections of a channel.
-typedef std::vector<ConnectionInfo> ConnectionInfos;
-
-// Information about a specific channel
-struct TransportChannelStats {
-  TransportChannelStats();
-  TransportChannelStats(const TransportChannelStats&);
-  ~TransportChannelStats();
-
-  int component = 0;
-  ConnectionInfos connection_infos;
-  int srtp_crypto_suite = rtc::SRTP_INVALID_CRYPTO_SUITE;
-  int ssl_cipher_suite = rtc::TLS_NULL_WITH_NULL_NULL;
-  DtlsTransportState dtls_state = DTLS_TRANSPORT_NEW;
-};
-
-// Information about all the channels of a transport.
-// TODO(hta): Consider if a simple vector is as good as a map.
-typedef std::vector<TransportChannelStats> TransportChannelStatsList;
-
-// Information about the stats of a transport.
-struct TransportStats {
-  TransportStats();
-  ~TransportStats();
-
-  std::string transport_name;
-  TransportChannelStatsList channel_stats;
-};
-
-// ICE Nomination mode.
-enum class NominationMode {
-  REGULAR,         // Nominate once per ICE restart (Not implemented yet).
-  AGGRESSIVE,      // Nominate every connection except that it will behave as if
-                   // REGULAR when the remote is an ICE-LITE endpoint.
-  SEMI_AGGRESSIVE  // Our current implementation of the nomination algorithm.
-                   // The details are described in P2PTransportChannel.
-};
-
-// Information about ICE configuration.
-// TODO(deadbeef): Use rtc::Optional to represent unset values, instead of
-// -1.
-struct IceConfig {
-  // The ICE connection receiving timeout value in milliseconds.
-  int receiving_timeout = -1;
-  // Time interval in milliseconds to ping a backup connection when the ICE
-  // channel is strongly connected.
-  int backup_connection_ping_interval = -1;
-
-  ContinualGatheringPolicy continual_gathering_policy = GATHER_ONCE;
-
-  bool gather_continually() const {
-    return continual_gathering_policy == GATHER_CONTINUALLY ||
-           continual_gathering_policy == GATHER_CONTINUALLY_AND_RECOVER;
-  }
-
-  // Whether we should prioritize Relay/Relay candidate when nothing
-  // is writable yet.
-  bool prioritize_most_likely_candidate_pairs = false;
-
-  // Writable connections are pinged at a slower rate once stablized.
-  int stable_writable_connection_ping_interval = -1;
-
-  // If set to true, this means the ICE transport should presume TURN-to-TURN
-  // candidate pairs will succeed, even before a binding response is received.
-  bool presume_writable_when_fully_relayed = false;
-
-  // Interval to check on all networks and to perform ICE regathering on any
-  // active network having no connection on it.
-  rtc::Optional<int> regather_on_failed_networks_interval;
-
-  // Interval to perform ICE regathering on all networks
-  // The delay in milliseconds is sampled from the uniform distribution [a, b]
-  rtc::Optional<rtc::IntervalRange> regather_all_networks_interval_range;
-
-  // The time period in which we will not switch the selected connection
-  // when a new connection becomes receiving but the selected connection is not
-  // in case that the selected connection may become receiving soon.
-  rtc::Optional<int> receiving_switching_delay;
-
-  // TODO(honghaiz): Change the default to regular nomination.
-  // Default nomination mode if the remote does not support renomination.
-  NominationMode default_nomination_mode = NominationMode::SEMI_AGGRESSIVE;
-
-  // ICE checks (STUN pings) will not be sent at higher rate (lower interval)
-  // than this, no matter what other settings there are.
-  // Measure in milliseconds.
-  rtc::Optional<int> ice_check_min_interval;
-
-  IceConfig();
-  IceConfig(int receiving_timeout_ms,
-            int backup_connection_ping_interval,
-            ContinualGatheringPolicy gathering_policy,
-            bool prioritize_most_likely_candidate_pairs,
-            int stable_writable_connection_ping_interval_ms,
-            bool presume_writable_when_fully_relayed,
-            int regather_on_failed_networks_interval_ms,
-            int receiving_switching_delay_ms);
-  ~IceConfig();
-};
-
-bool BadTransportDescription(const std::string& desc, std::string* err_desc);
-
-bool IceCredentialsChanged(const std::string& old_ufrag,
-                           const std::string& old_pwd,
-                           const std::string& new_ufrag,
-                           const std::string& new_pwd);
-
-// If a candidate is not acceptable, returns false and sets error.
-bool VerifyCandidate(const Candidate& candidate, std::string* error);
-bool VerifyCandidates(const Candidates& candidates, std::string* error);
-
-// Helper class used by TransportController that processes
-// TransportDescriptions. A TransportDescription represents the
-// transport-specific properties of an SDP m= section, processed according to
-// JSEP. Each transport consists of DTLS and ICE transport channels for RTP
-// (and possibly RTCP, if rtcp-mux isn't used).
-//
-// On Threading:  Transport performs work solely on the network thread, and so
-// its methods should only be called on the network thread.
-//
-// TODO(deadbeef): Move this into /pc/ and out of /p2p/base/, since it's
-// PeerConnection-specific.
-class JsepTransport : public sigslot::has_slots<> {
- public:
-  // |mid| is just used for log statements in order to identify the Transport.
-  // Note that |certificate| is allowed to be null since a remote description
-  // may be set before a local certificate is generated.
-  JsepTransport(const std::string& mid,
-                const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);
-  ~JsepTransport() override;
-
-  // Returns the MID of this transport.
-  const std::string& mid() const { return mid_; }
-
-  // Add or remove channel that is affected when a local/remote transport
-  // description is set on this transport. Need to add all channels before
-  // setting a transport description.
-  bool AddChannel(DtlsTransportInternal* dtls, int component);
-  bool RemoveChannel(int component);
-  bool HasChannels() const;
-
-  bool ready_for_remote_candidates() const {
-    return local_description_set_ && remote_description_set_;
-  }
-
-  // Must be called before applying local session description.
-  // Needed in order to verify the local fingerprint.
-  void SetLocalCertificate(
-      const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);
-
-  // Get a copy of the local certificate provided by SetLocalCertificate.
-  bool GetLocalCertificate(
-      rtc::scoped_refptr<rtc::RTCCertificate>* certificate) const;
-
-  // Set the local TransportDescription to be used by DTLS and ICE channels
-  // that are part of this Transport.
-  bool SetLocalTransportDescription(const TransportDescription& description,
-                                    webrtc::SdpType type,
-                                    std::string* error_desc);
-
-  // Set the remote TransportDescription to be used by DTLS and ICE channels
-  // that are part of this Transport.
-  bool SetRemoteTransportDescription(const TransportDescription& description,
-                                     webrtc::SdpType type,
-                                     std::string* error_desc);
-
-  // Set the "needs-ice-restart" flag as described in JSEP. After the flag is
-  // set, offers should generate new ufrags/passwords until an ICE restart
-  // occurs.
-  //
-  // This and the below method can be called safely from any thread as long as
-  // SetXTransportDescription is not in progress.
-  void SetNeedsIceRestartFlag();
-  // Returns true if the ICE restart flag above was set, and no ICE restart has
-  // occurred yet for this transport (by applying a local description with
-  // changed ufrag/password).
-  bool NeedsIceRestart() const;
-
-  // Returns role if negotiated, or empty Optional if it hasn't been negotiated
-  // yet.
-  rtc::Optional<rtc::SSLRole> GetSslRole() const;
-
-  // TODO(deadbeef): Make this const. See comment in transportcontroller.h.
-  bool GetStats(TransportStats* stats);
-
-  // The current local transport description, possibly used
-  // by the transport controller.
-  const TransportDescription* local_description() const {
-    return local_description_.get();
-  }
-
-  // The current remote transport description, possibly used
-  // by the transport controller.
-  const TransportDescription* remote_description() const {
-    return remote_description_.get();
-  }
-
-  // TODO(deadbeef): The methods below are only public for testing. Should make
-  // them utility functions or objects so they can be tested independently from
-  // this class.
-
-  // Returns false if the certificate's identity does not match the fingerprint,
-  // or either is NULL.
-  bool VerifyCertificateFingerprint(const rtc::RTCCertificate* certificate,
-                                    const rtc::SSLFingerprint* fingerprint,
-                                    std::string* error_desc) const;
-
- private:
-  // Negotiates the transport parameters based on the current local and remote
-  // transport description, such as the ICE role to use, and whether DTLS
-  // should be activated.
-  //
-  // Called when an answer TransportDescription is applied.
-  bool NegotiateTransportDescription(webrtc::SdpType local_description_type,
-                                     std::string* error_desc);
-
-  // Negotiates the SSL role based off the offer and answer as specified by
-  // RFC 4145, section-4.1. Returns false if the SSL role cannot be determined
-  // from the local description and remote description.
-  bool NegotiateRole(webrtc::SdpType local_description_type,
-                     std::string* error_desc);
-
-  // Pushes down the transport parameters from the local description, such
-  // as the ICE ufrag and pwd.
-  bool ApplyLocalTransportDescription(DtlsTransportInternal* dtls_transport,
-                                      std::string* error_desc);
-
-  // Pushes down the transport parameters from the remote description to the
-  // transport channel.
-  bool ApplyRemoteTransportDescription(DtlsTransportInternal* dtls_transport,
-                                       std::string* error_desc);
-
-  // Pushes down the transport parameters obtained via negotiation.
-  bool ApplyNegotiatedTransportDescription(
-      DtlsTransportInternal* dtls_transport,
-      std::string* error_desc);
-
-  const std::string mid_;
-  // needs-ice-restart bit as described in JSEP.
-  bool needs_ice_restart_ = false;
-  rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
-  rtc::Optional<rtc::SSLRole> ssl_role_;
-  std::unique_ptr<rtc::SSLFingerprint> remote_fingerprint_;
-  std::unique_ptr<TransportDescription> local_description_;
-  std::unique_ptr<TransportDescription> remote_description_;
-  bool local_description_set_ = false;
-  bool remote_description_set_ = false;
-
-  // Candidate component => DTLS channel
-  std::map<int, DtlsTransportInternal*> channels_;
-
-  RTC_DISALLOW_COPY_AND_ASSIGN(JsepTransport);
-};
-
-}  // namespace cricket
+}
 
 #endif  // P2P_BASE_JSEPTRANSPORT_H_
diff --git a/p2p/base/mockicetransport.h b/p2p/base/mockicetransport.h
index c77f8b1..3e7aed7 100644
--- a/p2p/base/mockicetransport.h
+++ b/p2p/base/mockicetransport.h
@@ -41,8 +41,6 @@
   MOCK_METHOD0(GetError, int());
   MOCK_CONST_METHOD0(GetIceRole, cricket::IceRole());
   MOCK_METHOD1(GetStats, bool(cricket::ConnectionInfos* infos));
-  MOCK_CONST_METHOD0(IsDtlsActive, bool());
-  MOCK_CONST_METHOD1(GetSslRole, bool(rtc::SSLRole* role));
 
   IceTransportState GetState() const override {
     return IceTransportState::STATE_INIT;
diff --git a/p2p/base/p2ptransportchannel.cc b/p2p/base/p2ptransportchannel.cc
index e7564fa..ddd2403 100644
--- a/p2p/base/p2ptransportchannel.cc
+++ b/p2p/base/p2ptransportchannel.cc
@@ -101,6 +101,17 @@
 static constexpr int a_is_better = 1;
 static constexpr int b_is_better = -1;
 
+bool IceCredentialsChanged(const std::string& old_ufrag,
+                           const std::string& old_pwd,
+                           const std::string& new_ufrag,
+                           const std::string& new_pwd) {
+  // The standard (RFC 5245 Section 9.1.1.1) says that ICE restarts MUST change
+  // both the ufrag and password. However, section 9.2.1.1 says changing the
+  // ufrag OR password indicates an ICE restart. So, to keep compatibility with
+  // endpoints that only change one, we'll treat this as an ICE restart.
+  return (old_ufrag != new_ufrag) || (old_pwd != new_pwd);
+}
+
 P2PTransportChannel::P2PTransportChannel(const std::string& transport_name,
                                          int component,
                                          PortAllocator* allocator)
diff --git a/p2p/base/p2ptransportchannel.h b/p2p/base/p2ptransportchannel.h
index 188f60c..c2febbf 100644
--- a/p2p/base/p2ptransportchannel.h
+++ b/p2p/base/p2ptransportchannel.h
@@ -48,6 +48,11 @@
 extern const int STRONG_AND_STABLE_WRITABLE_CONNECTION_PING_INTERVAL;
 static const int MIN_PINGS_AT_WEAK_PING_INTERVAL = 3;
 
+bool IceCredentialsChanged(const std::string& old_ufrag,
+                           const std::string& old_pwd,
+                           const std::string& new_ufrag,
+                           const std::string& new_pwd);
+
 // Adds the port on which the candidate originated.
 class RemoteCandidate : public Candidate {
  public:
diff --git a/p2p/base/port.cc b/p2p/base/port.cc
index af96582..21b817a 100644
--- a/p2p/base/port.cc
+++ b/p2p/base/port.cc
@@ -139,6 +139,34 @@
   return rtc::ToString<uint32_t>(rtc::ComputeCrc32(ost.str()));
 }
 
+ConnectionInfo::ConnectionInfo()
+    : best_connection(false),
+      writable(false),
+      receiving(false),
+      timeout(false),
+      new_connection(false),
+      rtt(0),
+      sent_total_bytes(0),
+      sent_bytes_second(0),
+      sent_discarded_packets(0),
+      sent_total_packets(0),
+      sent_ping_requests_total(0),
+      sent_ping_requests_before_first_response(0),
+      sent_ping_responses(0),
+      recv_total_bytes(0),
+      recv_bytes_second(0),
+      recv_ping_requests(0),
+      recv_ping_responses(0),
+      key(nullptr),
+      state(IceCandidatePairState::WAITING),
+      priority(0),
+      nominated(false),
+      total_round_trip_time_ms(0) {}
+
+ConnectionInfo::ConnectionInfo(const ConnectionInfo&) = default;
+
+ConnectionInfo::~ConnectionInfo() = default;
+
 Port::Port(rtc::Thread* thread,
            const std::string& type,
            rtc::PacketSocketFactory* factory,
diff --git a/p2p/base/port.h b/p2p/base/port.h
index e56afc4..ca845e6 100644
--- a/p2p/base/port.h
+++ b/p2p/base/port.h
@@ -20,7 +20,6 @@
 #include "api/candidate.h"
 #include "api/optional.h"
 #include "p2p/base/candidatepairinterface.h"
-#include "p2p/base/jseptransport.h"
 #include "p2p/base/packetlossestimator.h"
 #include "p2p/base/packetsocketfactory.h"
 #include "p2p/base/portinterface.h"
@@ -104,6 +103,52 @@
   // frozen because we have not implemented ICE freezing logic.
 };
 
+// Stats that we can return about the connections for a transport channel.
+// TODO(hta): Rename to ConnectionStats
+struct ConnectionInfo {
+  ConnectionInfo();
+  ConnectionInfo(const ConnectionInfo&);
+  ~ConnectionInfo();
+
+  bool best_connection;      // Is this the best connection we have?
+  bool writable;             // Has this connection received a STUN response?
+  bool receiving;            // Has this connection received anything?
+  bool timeout;              // Has this connection timed out?
+  bool new_connection;       // Is this a newly created connection?
+  size_t rtt;                // The STUN RTT for this connection.
+  size_t sent_total_bytes;   // Total bytes sent on this connection.
+  size_t sent_bytes_second;  // Bps over the last measurement interval.
+  size_t sent_discarded_packets;  // Number of outgoing packets discarded due to
+                                  // socket errors.
+  size_t sent_total_packets;  // Number of total outgoing packets attempted for
+                              // sending.
+  size_t sent_ping_requests_total;  // Number of STUN ping request sent.
+  size_t sent_ping_requests_before_first_response;  // Number of STUN ping
+  // sent before receiving the first response.
+  size_t sent_ping_responses;  // Number of STUN ping response sent.
+
+  size_t recv_total_bytes;     // Total bytes received on this connection.
+  size_t recv_bytes_second;    // Bps over the last measurement interval.
+  size_t recv_ping_requests;   // Number of STUN ping request received.
+  size_t recv_ping_responses;  // Number of STUN ping response received.
+  Candidate local_candidate;   // The local candidate for this connection.
+  Candidate remote_candidate;  // The remote candidate for this connection.
+  void* key;                   // A static value that identifies this conn.
+  // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-state
+  IceCandidatePairState state;
+  // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-priority
+  uint64_t priority;
+  // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-nominated
+  bool nominated;
+  // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-totalroundtriptime
+  uint64_t total_round_trip_time_ms;
+  // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-currentroundtriptime
+  rtc::Optional<uint32_t> current_round_trip_time_ms;
+};
+
+// Information about all the connections of a channel.
+typedef std::vector<ConnectionInfo> ConnectionInfos;
+
 const char* ProtoToString(ProtocolType proto);
 bool StringToProto(const char* value, ProtocolType* proto);
 
diff --git a/p2p/base/port_unittest.cc b/p2p/base/port_unittest.cc
index d657947..438e4e6 100644
--- a/p2p/base/port_unittest.cc
+++ b/p2p/base/port_unittest.cc
@@ -12,7 +12,6 @@
 #include <memory>
 
 #include "p2p/base/basicpacketsocketfactory.h"
-#include "p2p/base/jseptransport.h"
 #include "p2p/base/relayport.h"
 #include "p2p/base/stunport.h"
 #include "p2p/base/tcpport.h"
diff --git a/p2p/base/portinterface.h b/p2p/base/portinterface.h
index 6b97fec..e34e39a 100644
--- a/p2p/base/portinterface.h
+++ b/p2p/base/portinterface.h
@@ -14,7 +14,8 @@
 #include <string>
 #include <vector>
 
-#include "p2p/base/jseptransport.h"
+#include "api/candidate.h"
+#include "p2p/base/transportdescription.h"
 #include "rtc_base/asyncpacketsocket.h"
 #include "rtc_base/socketaddress.h"
 
diff --git a/p2p/client/socketmonitor.h b/p2p/client/socketmonitor.h
index 6889803..3428b03 100644
--- a/p2p/client/socketmonitor.h
+++ b/p2p/client/socketmonitor.h
@@ -13,7 +13,7 @@
 
 #include <vector>
 
-#include "p2p/base/jseptransport.h"  // for ConnectionInfos
+#include "p2p/base/port.h"  // for ConnectionInfos
 #include "rtc_base/criticalsection.h"
 #include "rtc_base/sigslot.h"
 #include "rtc_base/thread.h"
diff --git a/pc/BUILD.gn b/pc/BUILD.gn
index ba1d8a7..aa5a5f4 100644
--- a/pc/BUILD.gn
+++ b/pc/BUILD.gn
@@ -42,6 +42,8 @@
     "dtlssrtptransport.h",
     "externalhmac.cc",
     "externalhmac.h",
+    "jseptransport.cc",
+    "jseptransport.h",
     "mediamonitor.cc",
     "mediamonitor.h",
     "mediasession.cc",
@@ -257,6 +259,7 @@
       "channelmanager_unittest.cc",
       "currentspeakermonitor_unittest.cc",
       "dtlssrtptransport_unittest.cc",
+      "jseptransport_unittest.cc",
       "mediasession_unittest.cc",
       "rtcpmuxfilter_unittest.cc",
       "rtptransport_unittest.cc",
diff --git a/p2p/base/jseptransport.cc b/pc/jseptransport.cc
similarity index 79%
rename from p2p/base/jseptransport.cc
rename to pc/jseptransport.cc
index 77ea040..12aad7a 100644
--- a/p2p/base/jseptransport.cc
+++ b/pc/jseptransport.cc
@@ -8,13 +8,12 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#include "p2p/base/jseptransport.h"
+#include "pc/jseptransport.h"
 
 #include <memory>
 #include <utility>  // for std::pair
 
 #include "api/candidate.h"
-#include "p2p/base/dtlstransport.h"
 #include "p2p/base/p2pconstants.h"
 #include "p2p/base/p2ptransportchannel.h"
 #include "p2p/base/port.h"
@@ -26,6 +25,25 @@
 
 namespace cricket {
 
+TransportChannelStats::TransportChannelStats() = default;
+
+TransportChannelStats::TransportChannelStats(const TransportChannelStats&) =
+    default;
+
+TransportChannelStats::~TransportChannelStats() = default;
+
+TransportStats::TransportStats() = default;
+
+TransportStats::~TransportStats() = default;
+
+bool BadTransportDescription(const std::string& desc, std::string* err_desc) {
+  if (err_desc) {
+    *err_desc = desc;
+  }
+  RTC_LOG(LS_ERROR) << desc;
+  return false;
+}
+
 static bool VerifyIceParams(const TransportDescription& desc) {
   // For legacy protocols.
   if (desc.ice_ufrag.empty() && desc.ice_pwd.empty())
@@ -42,128 +60,6 @@
   return true;
 }
 
-ConnectionInfo::ConnectionInfo()
-    : best_connection(false),
-      writable(false),
-      receiving(false),
-      timeout(false),
-      new_connection(false),
-      rtt(0),
-      sent_total_bytes(0),
-      sent_bytes_second(0),
-      sent_discarded_packets(0),
-      sent_total_packets(0),
-      sent_ping_requests_total(0),
-      sent_ping_requests_before_first_response(0),
-      sent_ping_responses(0),
-      recv_total_bytes(0),
-      recv_bytes_second(0),
-      recv_ping_requests(0),
-      recv_ping_responses(0),
-      key(nullptr),
-      state(IceCandidatePairState::WAITING),
-      priority(0),
-      nominated(false),
-      total_round_trip_time_ms(0) {}
-
-ConnectionInfo::ConnectionInfo(const ConnectionInfo&) = default;
-
-ConnectionInfo::~ConnectionInfo() = default;
-
-TransportChannelStats::TransportChannelStats() = default;
-
-TransportChannelStats::TransportChannelStats(const TransportChannelStats&) =
-    default;
-
-TransportChannelStats::~TransportChannelStats() = default;
-
-TransportStats::TransportStats() = default;
-
-TransportStats::~TransportStats() = default;
-
-IceConfig::IceConfig() = default;
-
-IceConfig::IceConfig(int receiving_timeout_ms,
-                     int backup_connection_ping_interval,
-                     ContinualGatheringPolicy gathering_policy,
-                     bool prioritize_most_likely_candidate_pairs,
-                     int stable_writable_connection_ping_interval_ms,
-                     bool presume_writable_when_fully_relayed,
-                     int regather_on_failed_networks_interval_ms,
-                     int receiving_switching_delay_ms)
-    : receiving_timeout(receiving_timeout_ms),
-      backup_connection_ping_interval(backup_connection_ping_interval),
-      continual_gathering_policy(gathering_policy),
-      prioritize_most_likely_candidate_pairs(
-          prioritize_most_likely_candidate_pairs),
-      stable_writable_connection_ping_interval(
-          stable_writable_connection_ping_interval_ms),
-      presume_writable_when_fully_relayed(presume_writable_when_fully_relayed),
-      regather_on_failed_networks_interval(
-          regather_on_failed_networks_interval_ms),
-      receiving_switching_delay(receiving_switching_delay_ms) {}
-
-IceConfig::~IceConfig() = default;
-
-bool BadTransportDescription(const std::string& desc, std::string* err_desc) {
-  if (err_desc) {
-    *err_desc = desc;
-  }
-  RTC_LOG(LS_ERROR) << desc;
-  return false;
-}
-
-bool IceCredentialsChanged(const std::string& old_ufrag,
-                           const std::string& old_pwd,
-                           const std::string& new_ufrag,
-                           const std::string& new_pwd) {
-  // The standard (RFC 5245 Section 9.1.1.1) says that ICE restarts MUST change
-  // both the ufrag and password. However, section 9.2.1.1 says changing the
-  // ufrag OR password indicates an ICE restart. So, to keep compatibility with
-  // endpoints that only change one, we'll treat this as an ICE restart.
-  return (old_ufrag != new_ufrag) || (old_pwd != new_pwd);
-}
-
-bool VerifyCandidate(const Candidate& cand, std::string* error) {
-  // No address zero.
-  if (cand.address().IsNil() || cand.address().IsAnyIP()) {
-    *error = "candidate has address of zero";
-    return false;
-  }
-
-  // Disallow all ports below 1024, except for 80 and 443 on public addresses.
-  int port = cand.address().port();
-  if (cand.protocol() == TCP_PROTOCOL_NAME &&
-      (cand.tcptype() == TCPTYPE_ACTIVE_STR || port == 0)) {
-    // Expected for active-only candidates per
-    // http://tools.ietf.org/html/rfc6544#section-4.5 so no error.
-    // Libjingle clients emit port 0, in "active" mode.
-    return true;
-  }
-  if (port < 1024) {
-    if ((port != 80) && (port != 443)) {
-      *error = "candidate has port below 1024, but not 80 or 443";
-      return false;
-    }
-
-    if (cand.address().IsPrivateIP()) {
-      *error = "candidate has port of 80 or 443 with private IP address";
-      return false;
-    }
-  }
-
-  return true;
-}
-
-bool VerifyCandidates(const Candidates& candidates, std::string* error) {
-  for (const Candidate& candidate : candidates) {
-    if (!VerifyCandidate(candidate, error)) {
-      return false;
-    }
-  }
-  return true;
-}
-
 JsepTransport::JsepTransport(
     const std::string& mid,
     const rtc::scoped_refptr<rtc::RTCCertificate>& certificate)
diff --git a/pc/jseptransport.h b/pc/jseptransport.h
new file mode 100644
index 0000000..068078b
--- /dev/null
+++ b/pc/jseptransport.h
@@ -0,0 +1,205 @@
+/*
+ *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef PC_JSEPTRANSPORT_H_
+#define PC_JSEPTRANSPORT_H_
+
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "api/candidate.h"
+#include "api/jsep.h"
+#include "api/optional.h"
+#include "p2p/base/dtlstransport.h"
+#include "p2p/base/p2pconstants.h"
+#include "p2p/base/sessiondescription.h"
+#include "p2p/base/transportinfo.h"
+#include "rtc_base/constructormagic.h"
+#include "rtc_base/messagequeue.h"
+#include "rtc_base/rtccertificate.h"
+#include "rtc_base/sigslot.h"
+#include "rtc_base/sslstreamadapter.h"
+
+namespace cricket {
+
+class DtlsTransportInternal;
+
+struct TransportChannelStats {
+  TransportChannelStats();
+  TransportChannelStats(const TransportChannelStats&);
+  ~TransportChannelStats();
+
+  int component = 0;
+  ConnectionInfos connection_infos;
+  int srtp_crypto_suite = rtc::SRTP_INVALID_CRYPTO_SUITE;
+  int ssl_cipher_suite = rtc::TLS_NULL_WITH_NULL_NULL;
+  DtlsTransportState dtls_state = DTLS_TRANSPORT_NEW;
+};
+
+// Information about all the channels of a transport.
+// TODO(hta): Consider if a simple vector is as good as a map.
+typedef std::vector<TransportChannelStats> TransportChannelStatsList;
+
+// Information about the stats of a transport.
+struct TransportStats {
+  TransportStats();
+  ~TransportStats();
+
+  std::string transport_name;
+  TransportChannelStatsList channel_stats;
+};
+
+bool BadTransportDescription(const std::string& desc, std::string* err_desc);
+
+// Helper class used by TransportController that processes
+// TransportDescriptions. A TransportDescription represents the
+// transport-specific properties of an SDP m= section, processed according to
+// JSEP. Each transport consists of DTLS and ICE transport channels for RTP
+// (and possibly RTCP, if rtcp-mux isn't used).
+//
+// On Threading:  Transport performs work solely on the network thread, and so
+// its methods should only be called on the network thread.
+class JsepTransport : public sigslot::has_slots<> {
+ public:
+  // |mid| is just used for log statements in order to identify the Transport.
+  // Note that |certificate| is allowed to be null since a remote description
+  // may be set before a local certificate is generated.
+  JsepTransport(const std::string& mid,
+                const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);
+  ~JsepTransport() override;
+
+  // Returns the MID of this transport.
+  const std::string& mid() const { return mid_; }
+
+  // Add or remove channel that is affected when a local/remote transport
+  // description is set on this transport. Need to add all channels before
+  // setting a transport description.
+  bool AddChannel(DtlsTransportInternal* dtls, int component);
+  bool RemoveChannel(int component);
+  bool HasChannels() const;
+
+  bool ready_for_remote_candidates() const {
+    return local_description_set_ && remote_description_set_;
+  }
+
+  // Must be called before applying local session description.
+  // Needed in order to verify the local fingerprint.
+  void SetLocalCertificate(
+      const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);
+
+  // Get a copy of the local certificate provided by SetLocalCertificate.
+  bool GetLocalCertificate(
+      rtc::scoped_refptr<rtc::RTCCertificate>* certificate) const;
+
+  // Set the local TransportDescription to be used by DTLS and ICE channels
+  // that are part of this Transport.
+  bool SetLocalTransportDescription(const TransportDescription& description,
+                                    webrtc::SdpType type,
+                                    std::string* error_desc);
+
+  // Set the remote TransportDescription to be used by DTLS and ICE channels
+  // that are part of this Transport.
+  bool SetRemoteTransportDescription(const TransportDescription& description,
+                                     webrtc::SdpType type,
+                                     std::string* error_desc);
+
+  // Set the "needs-ice-restart" flag as described in JSEP. After the flag is
+  // set, offers should generate new ufrags/passwords until an ICE restart
+  // occurs.
+  //
+  // This and the below method can be called safely from any thread as long as
+  // SetXTransportDescription is not in progress.
+  void SetNeedsIceRestartFlag();
+  // Returns true if the ICE restart flag above was set, and no ICE restart has
+  // occurred yet for this transport (by applying a local description with
+  // changed ufrag/password).
+  bool NeedsIceRestart() const;
+
+  // Returns role if negotiated, or empty Optional if it hasn't been negotiated
+  // yet.
+  rtc::Optional<rtc::SSLRole> GetSslRole() const;
+
+  // TODO(deadbeef): Make this const. See comment in transportcontroller.h.
+  bool GetStats(TransportStats* stats);
+
+  // The current local transport description, possibly used
+  // by the transport controller.
+  const TransportDescription* local_description() const {
+    return local_description_.get();
+  }
+
+  // The current remote transport description, possibly used
+  // by the transport controller.
+  const TransportDescription* remote_description() const {
+    return remote_description_.get();
+  }
+
+  // TODO(deadbeef): The methods below are only public for testing. Should make
+  // them utility functions or objects so they can be tested independently from
+  // this class.
+
+  // Returns false if the certificate's identity does not match the fingerprint,
+  // or either is NULL.
+  bool VerifyCertificateFingerprint(const rtc::RTCCertificate* certificate,
+                                    const rtc::SSLFingerprint* fingerprint,
+                                    std::string* error_desc) const;
+
+ private:
+  // Negotiates the transport parameters based on the current local and remote
+  // transport description, such as the ICE role to use, and whether DTLS
+  // should be activated.
+  //
+  // Called when an answer TransportDescription is applied.
+  bool NegotiateTransportDescription(webrtc::SdpType local_description_type,
+                                     std::string* error_desc);
+
+  // Negotiates the SSL role based off the offer and answer as specified by
+  // RFC 4145, section-4.1. Returns false if the SSL role cannot be determined
+  // from the local description and remote description.
+  bool NegotiateRole(webrtc::SdpType local_description_type,
+                     std::string* error_desc);
+
+  // Pushes down the transport parameters from the local description, such
+  // as the ICE ufrag and pwd.
+  bool ApplyLocalTransportDescription(DtlsTransportInternal* dtls_transport,
+                                      std::string* error_desc);
+
+  // Pushes down the transport parameters from the remote description to the
+  // transport channel.
+  bool ApplyRemoteTransportDescription(DtlsTransportInternal* dtls_transport,
+                                       std::string* error_desc);
+
+  // Pushes down the transport parameters obtained via negotiation.
+  bool ApplyNegotiatedTransportDescription(
+      DtlsTransportInternal* dtls_transport,
+      std::string* error_desc);
+
+  const std::string mid_;
+  // needs-ice-restart bit as described in JSEP.
+  bool needs_ice_restart_ = false;
+  rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
+  rtc::Optional<rtc::SSLRole> ssl_role_;
+  std::unique_ptr<rtc::SSLFingerprint> remote_fingerprint_;
+  std::unique_ptr<TransportDescription> local_description_;
+  std::unique_ptr<TransportDescription> remote_description_;
+  bool local_description_set_ = false;
+  bool remote_description_set_ = false;
+
+  // Candidate component => DTLS channel
+  std::map<int, DtlsTransportInternal*> channels_;
+
+  RTC_DISALLOW_COPY_AND_ASSIGN(JsepTransport);
+};
+
+}  // namespace cricket
+
+#endif  // PC_JSEPTRANSPORT_H_
diff --git a/p2p/base/jseptransport_unittest.cc b/pc/jseptransport_unittest.cc
similarity index 98%
rename from p2p/base/jseptransport_unittest.cc
rename to pc/jseptransport_unittest.cc
index bcd12c5..1111f36 100644
--- a/p2p/base/jseptransport_unittest.cc
+++ b/pc/jseptransport_unittest.cc
@@ -7,6 +7,7 @@
  *  in the file PATENTS.  All contributing project authors may
  *  be found in the AUTHORS file in the root of the source tree.
  */
+#include "pc/jseptransport.h"
 
 #include <memory>
 
@@ -59,6 +60,13 @@
     transport_.reset(new JsepTransport("test content name", nullptr));
   }
 
+  bool IceCredentialsChanged(const std::string& old_ufrag,
+                             const std::string& old_pwd,
+                             const std::string& new_ufrag,
+                             const std::string& new_pwd) {
+    return (old_ufrag != new_ufrag) || (old_pwd != new_pwd);
+  }
+
  protected:
   std::vector<std::unique_ptr<FakeDtlsTransport>> fake_dtls_transports_;
   std::vector<std::unique_ptr<FakeIceTransport>> fake_ice_transports_;
diff --git a/pc/mediasession.h b/pc/mediasession.h
index bfce245..784aad8 100644
--- a/pc/mediasession.h
+++ b/pc/mediasession.h
@@ -26,9 +26,9 @@
 #include "media/base/mediaconstants.h"
 #include "media/base/mediaengine.h"  // For DataChannelType
 #include "media/base/streamparams.h"
-#include "p2p/base/jseptransport.h"
 #include "p2p/base/sessiondescription.h"
 #include "p2p/base/transportdescriptionfactory.h"
+#include "pc/jseptransport.h"
 
 namespace cricket {
 
diff --git a/pc/transportcontroller.cc b/pc/transportcontroller.cc
index a9b030c..bd9ea75 100644
--- a/pc/transportcontroller.cc
+++ b/pc/transportcontroller.cc
@@ -40,6 +40,47 @@
   cricket::Candidates candidates;
 };
 
+bool VerifyCandidate(const cricket::Candidate& cand, std::string* error) {
+  // No address zero.
+  if (cand.address().IsNil() || cand.address().IsAnyIP()) {
+    *error = "candidate has address of zero";
+    return false;
+  }
+
+  // Disallow all ports below 1024, except for 80 and 443 on public addresses.
+  int port = cand.address().port();
+  if (cand.protocol() == cricket::TCP_PROTOCOL_NAME &&
+      (cand.tcptype() == cricket::TCPTYPE_ACTIVE_STR || port == 0)) {
+    // Expected for active-only candidates per
+    // http://tools.ietf.org/html/rfc6544#section-4.5 so no error.
+    // Libjingle clients emit port 0, in "active" mode.
+    return true;
+  }
+  if (port < 1024) {
+    if ((port != 80) && (port != 443)) {
+      *error = "candidate has port below 1024, but not 80 or 443";
+      return false;
+    }
+
+    if (cand.address().IsPrivateIP()) {
+      *error = "candidate has port of 80 or 443 with private IP address";
+      return false;
+    }
+  }
+
+  return true;
+}
+
+bool VerifyCandidates(const cricket::Candidates& candidates,
+                      std::string* error) {
+  for (const cricket::Candidate& candidate : candidates) {
+    if (!VerifyCandidate(candidate, error)) {
+      return false;
+    }
+  }
+  return true;
+}
+
 }  // namespace
 
 namespace cricket {
diff --git a/pc/transportcontroller.h b/pc/transportcontroller.h
index bdde172..67fab73 100644
--- a/pc/transportcontroller.h
+++ b/pc/transportcontroller.h
@@ -18,9 +18,9 @@
 
 #include "api/candidate.h"
 #include "p2p/base/dtlstransport.h"
-#include "p2p/base/jseptransport.h"
 #include "p2p/base/p2ptransportchannel.h"
 #include "pc/dtlssrtptransport.h"
+#include "pc/jseptransport.h"
 #include "pc/rtptransport.h"
 #include "pc/srtptransport.h"
 #include "rtc_base/asyncinvoker.h"