-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Jv convert ipv4 mapped ipv6 to ipv4 #1906
base: master
Are you sure you want to change the base?
Changes from 5 commits
955bf47
616ed45
6ff422b
1b25e8a
5bbed5b
2ecb5df
c57f611
5d2b933
d44451d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -40,12 +40,22 @@ bool ContainsPrivateNetwork(Address::Family family, NRadixTree tree) { | |||||
return tree.IsAnyIPNetSubset(family, private_networks_tree) || private_networks_tree.IsAnyIPNetSubset(family, tree); | ||||||
} | ||||||
|
||||||
void ConnectionTracker::UpdateConnectionNoLock(const Connection& conn, const ConnStatus& status) { | ||||||
Connection ipv4Conn = conn.ConvertToIPv4(); | ||||||
EmplaceOrUpdateNoLock(ipv4Conn, status); | ||||||
} | ||||||
|
||||||
void ConnectionTracker::UpdateConnection(const Connection& conn, int64_t timestamp, bool added) { | ||||||
WITH_LOCK(mutex_) { | ||||||
EmplaceOrUpdateNoLock(conn, ConnStatus(timestamp, added)); | ||||||
} | ||||||
} | ||||||
|
||||||
void ConnectionTracker::UpdateEndpointNoLock(const ContainerEndpoint& endpoint, const ConnStatus& status) { | ||||||
ContainerEndpoint ipv4Endpoint = endpoint.ConvertToIPv4(); | ||||||
EmplaceOrUpdateNoLock(ipv4Endpoint, status); | ||||||
} | ||||||
|
||||||
void ConnectionTracker::Update( | ||||||
const std::vector<Connection>& all_conns, | ||||||
const std::vector<ContainerEndpoint>& all_listen_endpoints, | ||||||
|
@@ -63,7 +73,7 @@ void ConnectionTracker::Update( | |||||
|
||||||
// Insert (or mark as active) all current connections and listen endpoints. | ||||||
for (const auto& curr_conn : all_conns) { | ||||||
EmplaceOrUpdateNoLock(curr_conn, new_status); | ||||||
UpdateConnectionNoLock(curr_conn, new_status); | ||||||
} | ||||||
for (const auto& curr_endpoint : all_listen_endpoints) { | ||||||
EmplaceOrUpdateNoLock(curr_endpoint, new_status); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -84,7 +84,9 @@ class CollectorStats; | |
|
||
class ConnectionTracker { | ||
public: | ||
void UpdateConnectionNoLock(const Connection& conn, const ConnStatus& status); | ||
void UpdateConnection(const Connection& conn, int64_t timestamp, bool added); | ||
void UpdateEndpointNoLock(const ContainerEndpoint& endpoint, const ConnStatus& status); | ||
void AddConnection(const Connection& conn, int64_t timestamp) { | ||
Comment on lines
+87
to
90
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should keep the |
||
UpdateConnection(conn, timestamp, true); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -137,6 +137,36 @@ class Address { | |
} | ||
} | ||
|
||
bool IsIPv4MappedIPv6() const { | ||
if (family_ != Family::IPV6) { | ||
return false; | ||
} | ||
|
||
const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data_.data()); | ||
|
||
// First 80 bits, 10 bytes, should be 0 if this is IPv4-Mapped IPv6 | ||
for (int i = 0; i < 10; i++) { | ||
if (bytes[i] != 0) { | ||
return false; | ||
} | ||
} | ||
|
||
// Next 2 bytes should be 0xFF if this is IPv4-Mapped IPv6 | ||
if (bytes[10] != 0xFF || bytes[11] != 0xFF) { | ||
return false; | ||
} | ||
Comment on lines
+215
to
+227
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For performance reasons, what about declaring a global const IPNet with the /96 mapped prefix, and using |
||
|
||
return true; | ||
} | ||
|
||
Address ConvertToIPv4() const { | ||
// Extract the last 32 bits of the IPv6 address, which is the IPv4 address part. | ||
const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data_.data()); | ||
|
||
// Last 4 bytes of the IPv6 address hold the IPv4 address | ||
return Address(bytes[12], bytes[13], bytes[14], bytes[15]); | ||
} | ||
|
||
private: | ||
friend std::ostream& operator<<(std::ostream& os, const Address& addr) { | ||
int af = (addr.family_ == Family::IPV4) ? AF_INET : AF_INET6; | ||
|
@@ -262,6 +292,16 @@ class IPNet { | |
return address_ > that.address_; | ||
} | ||
|
||
bool IsIPv4MappedIPv6() const { | ||
return address_.IsIPv4MappedIPv6(); | ||
} | ||
|
||
IPNet ConvertToIPv4() const { | ||
Address ipv4Address = address_.ConvertToIPv4(); | ||
size_t bits = bits_ - 96; // 96 = 128 - 32 | ||
return IPNet(ipv4Address, bits, is_addr_); | ||
} | ||
|
||
private: | ||
friend std::ostream& operator<<(std::ostream& os, const IPNet& net) { | ||
return os << net.address_ << "/" << net.bits_; | ||
|
@@ -299,6 +339,15 @@ class Endpoint { | |
return port_ == 0 && network_.IsNull(); | ||
} | ||
|
||
bool IsIPv4MappedIPv6() const { | ||
return network_.IsIPv4MappedIPv6(); | ||
} | ||
|
||
Endpoint ConvertToIPv4() const { | ||
IPNet network = network_.ConvertToIPv4(); | ||
return Endpoint(network, port_); | ||
} | ||
|
||
private: | ||
friend std::ostream& operator<<(std::ostream& os, const Endpoint& ep) { | ||
// This is an individual IP address. | ||
|
@@ -358,6 +407,14 @@ class ContainerEndpoint { | |
|
||
size_t Hash() const { return HashAll(container_, endpoint_, l4proto_); } | ||
|
||
ContainerEndpoint ConvertToIPv4() const { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The name is misleading as it suggests that the result is always IPv4 |
||
if (endpoint_.IsIPv4MappedIPv6()) { | ||
Endpoint ep = endpoint_.ConvertToIPv4(); | ||
return ContainerEndpoint(container_, ep, l4proto_, originator_); | ||
} | ||
return std::move(*this); | ||
} | ||
|
||
private: | ||
std::string container_; | ||
Endpoint endpoint_; | ||
|
@@ -389,6 +446,31 @@ class Connection { | |
|
||
size_t Hash() const { return HashAll(container_, local_, remote_, flags_); } | ||
|
||
Connection ConvertToIPv4() const { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change the name to |
||
bool localMapped = local_.IsIPv4MappedIPv6(); | ||
bool remoteMapped = remote_.IsIPv4MappedIPv6(); | ||
|
||
if (!localMapped && !remoteMapped) { | ||
return std::move(*this); | ||
} | ||
|
||
Endpoint local; | ||
if (localMapped) { | ||
local = local_.ConvertToIPv4(); | ||
} else { | ||
local = std::move(local_); | ||
} | ||
|
||
Endpoint remote; | ||
if (localMapped) { | ||
remote = remote_.ConvertToIPv4(); | ||
} else { | ||
remote = std::move(remote_); | ||
} | ||
|
||
return Connection(container_, local, remote, l4proto(), is_server()); | ||
} | ||
|
||
private: | ||
std::string container_; | ||
Endpoint local_; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ipv4Conn
is misleading, as as the result can be v6There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. I know. I should have called it something else or left a comment to remind myself to change the name.