Bug 1355947 - Add NatDelegate to TestNat; r=bwc
This allows tests to implement different packet handling schemes without having
to extend or modify TestNat itself.
MozReview-Commit-ID: 6DlESF3hfX6
--- a/media/mtransport/test_nr_socket.cpp
+++ b/media/mtransport/test_nr_socket.cpp
@@ -306,16 +306,20 @@ void TestNrSocket::process_delayed_cb(NR
delete op;
}
int TestNrSocket::sendto(const void *msg, size_t len,
int flags, nr_transport_addr *to) {
MOZ_ASSERT(internal_socket_->my_addr().protocol != IPPROTO_TCP);
+ if (nat_->nat_delegate_ && nat_->nat_delegate_->on_sendto(nat_, msg, len, flags, to)) {
+ return 0;
+ }
+
UCHAR *buf = static_cast<UCHAR*>(const_cast<void*>(msg));
if (nat_->block_stun_ &&
nr_is_stun_message(buf, len)) {
return 0;
}
/* TODO: improve the functionality of this in bug 1253657 */
if (!nat_->enabled_ || nat_->is_an_internal_tuple(*to)) {
@@ -512,16 +516,21 @@ int TestNrSocket::connect(nr_transport_a
__LINE__);
}
return r;
}
int TestNrSocket::write(const void *msg, size_t len, size_t *written) {
UCHAR *buf = static_cast<UCHAR*>(const_cast<void*>(msg));
+
+ if (nat_->nat_delegate_ && nat_->nat_delegate_->on_write(nat_, msg, len, written)) {
+ return R_INTERNAL;
+ }
+
if (nat_->block_stun_ && nr_is_stun_message(buf, len)) {
// Should cause this socket to be abandoned
r_log(LOG_GENERIC, LOG_DEBUG,
"TestNrSocket %s dropping outgoing TCP "
"because it is configured to drop STUN",
my_addr().as_string);
return R_INTERNAL;
}
@@ -572,16 +581,20 @@ int TestNrSocket::read(void *buf, size_t
port_mappings_.front()->last_used_ = PR_IntervalNow();
}
}
if (r) {
return r;
}
+ if (nat_->nat_delegate_ && nat_->nat_delegate_->on_read(nat_, buf, maxlen, len)) {
+ return R_INTERNAL;
+ }
+
if (nat_->block_tcp_ && !tls_) {
// Should cause this socket to be abandoned
return R_INTERNAL;
}
UCHAR *cbuf = static_cast<UCHAR*>(const_cast<void*>(buf));
if (nat_->block_stun_ && nr_is_stun_message(cbuf, *len)) {
// Should cause this socket to be abandoned
--- a/media/mtransport/test_nr_socket.h
+++ b/media/mtransport/test_nr_socket.h
@@ -108,16 +108,31 @@ class TestNrSocket;
/**
* A group of TestNrSockets that behave as if they were behind the same NAT.
* @note We deliberately avoid addref/release of TestNrSocket here to avoid
* masking lifetime errors elsewhere.
*/
class TestNat {
public:
+
+ /**
+ * This allows TestNat traffic to be passively inspected.
+ * If a non-zero (error) value is returned, the packet will be dropped,
+ * allowing for tests to extend how packet manipulation is done by
+ * TestNat with having to modify TestNat itself.
+ */
+ class NatDelegate {
+ public:
+ virtual int on_read(TestNat *nat, void *buf, size_t maxlen, size_t *len) = 0;
+ virtual int on_sendto(TestNat *nat, const void *msg, size_t len,
+ int flags, nr_transport_addr *to) = 0;
+ virtual int on_write(TestNat *nat, const void *msg, size_t len, size_t *written) = 0;
+ };
+
typedef enum {
/** For mapping, one port is used for all destinations.
* For filtering, allow any external address/port. */
ENDPOINT_INDEPENDENT,
/** For mapping, one port for each destination address (for any port).
* For filtering, allow incoming traffic from addresses that outgoing
* traffic has been sent to. */
@@ -135,16 +150,17 @@ class TestNat {
mapping_type_(ENDPOINT_INDEPENDENT),
mapping_timeout_(30000),
allow_hairpinning_(false),
refresh_on_ingress_(false),
block_udp_(false),
block_stun_(false),
block_tcp_(false),
delay_stun_resp_ms_(0),
+ nat_delegate_(nullptr),
sockets_() {}
bool has_port_mappings() const;
// Helps determine whether we're hairpinning
bool is_my_external_tuple(const nr_transport_addr &addr) const;
bool is_an_internal_tuple(const nr_transport_addr &addr) const;
@@ -169,16 +185,18 @@ class TestNat {
bool allow_hairpinning_;
bool refresh_on_ingress_;
bool block_udp_;
bool block_stun_;
bool block_tcp_;
/* Note: this can only delay a single response so far (bug 1253657) */
uint32_t delay_stun_resp_ms_;
+ NatDelegate* nat_delegate_;
+
private:
std::set<TestNrSocket*> sockets_;
~TestNat(){}
};
/**
* Subclass of NrSocketBase that can simulate things like being behind a NAT,