-
Notifications
You must be signed in to change notification settings - Fork 0
RAV-2958 - Add UDP Socket support #2
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
Merged
Merged
Changes from all commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
90cf559
RAV-2958 - Add UDP Socket support
bplessis-swi e250c97
disable integration test with nginx doesn't work
bplessis-swi 00f40ee
add subnet predicate helper
bplessis-swi fadd09d
process review step 2
bplessis-swi 07ee29c
fix tests
bplessis-swi d582239
Fix the handling on local mode in AwsProxyEncoderHelper
bplessis-swi 9977227
remove testcontainers
bplessis-swi 5998205
try to factor-in
bplessis-swi ddd5598
naming
bplessis-swi c1093d4
naming
bplessis-swi 322978c
Merge branch 'main' into RAV-2958_add_udp_socket
bplessis-swi 022e272
Switch to warn for packets dropped due to cache expiration
bplessis-swi d9f0dc5
fix name
bplessis-swi 59c285f
Update proxy-socket-udp/src/test/java/net/airvantage/proxysocket/udp/…
bplessis-swi 7ec9ee9
review comments
bplessis-swi 26bd11a
enforce address family and protocol in the build phase
bplessis-swi 15bcf03
review comments
bplessis-swi 68f3d59
fix licences
bplessis-swi 8c187da
fix licences
bplessis-swi 34cfc9a
process review
bplessis-swi c2bc5ea
revert throw
bplessis-swi 09b7c43
reduce try block
bplessis-swi 0eb3d7b
convert to parametized tests
bplessis-swi 1923df8
currently unused
bplessis-swi 76664a7
add a little documentation about using hostnames
bplessis-swi 4358848
reuse constructors
bplessis-swi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
160 changes: 160 additions & 0 deletions
160
proxy-socket-core/src/main/java/net/airvantage/proxysocket/tools/SubnetPredicate.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,160 @@ | ||
| /** | ||
| * BSD-3-Clause License. | ||
| * Copyright (c) 2025 Semtech | ||
| */ | ||
| package net.airvantage.proxysocket.tools; | ||
|
|
||
| import java.net.InetAddress; | ||
| import java.net.InetSocketAddress; | ||
| import java.net.UnknownHostException; | ||
| import java.util.function.Predicate; | ||
|
|
||
| /** | ||
| * Predicate compatible class that tests whether an InetSocketAddress belongs to a given subnet (CIDR). | ||
| * Supports both IPv4 and IPv6 CIDR notation. | ||
| * | ||
| * <p>Example usage: | ||
| * <pre> | ||
| * // Single subnet | ||
| * Predicate<InetSocketAddress> predicate = new SubnetPredicate("10.0.0.0/8"); | ||
| * | ||
| * // Multiple subnets | ||
| * Predicate<InetSocketAddress> predicate = | ||
| * new SubnetPredicate("10.0.0.0/8") | ||
| * .or(new SubnetPredicate("192.168.0.0/16")) | ||
| * .or(new SubnetPredicate("2001:db8::/32")) | ||
| * ); | ||
| * </pre> | ||
| * | ||
| * Note: it's possible to create a SubnetPredicate with a hostname instead of an IP address, | ||
| * the address will be resolved to an IP address using InetAddress.getByName(hostname). | ||
| * If the hostname is not resolvable, an IllegalArgumentException will be thrown. | ||
| * But if the hostname resolves to a mix of IPv4/IPv6 addresses or multiple addresses, | ||
| * the predicate will only match the first address found. | ||
| * | ||
| * Thread-safety: This class is immutable and thread-safe. | ||
| */ | ||
| public class SubnetPredicate implements Predicate<InetSocketAddress> { | ||
| private final byte[] networkAddress; | ||
| private final int prefixLength; | ||
| private final int addressLength; // 4 for IPv4, 16 for IPv6 | ||
|
|
||
| /** | ||
| * Creates a predicate for the given CIDR subnet. | ||
| * | ||
| * @param cidr CIDR notation string (e.g., "10.0.0.0/8" or "2001:db8::/32") | ||
| * @throws IllegalArgumentException if the CIDR notation is invalid | ||
| */ | ||
| public SubnetPredicate(String cidr) { | ||
| if (cidr == null || cidr.isEmpty()) { | ||
| throw new IllegalArgumentException("CIDR notation cannot be null or empty"); | ||
| } | ||
|
|
||
| int slashIndex = cidr.indexOf('/'); | ||
| if (slashIndex == -1) { | ||
| throw new IllegalArgumentException("Invalid CIDR notation: missing '/' separator"); | ||
| } | ||
|
|
||
| String addressPart = cidr.substring(0, slashIndex); | ||
| String prefixLengthPart = cidr.substring(slashIndex + 1); | ||
|
|
||
| try { | ||
| this.prefixLength = Integer.parseInt(prefixLengthPart); | ||
| } catch (NumberFormatException e) { | ||
| throw new IllegalArgumentException("Invalid prefix length: " + prefixLengthPart, e); | ||
| } | ||
|
|
||
| byte[] rawAddress; | ||
| try { | ||
| InetAddress addr = InetAddress.getByName(addressPart); | ||
| rawAddress = addr.getAddress(); | ||
| } catch (UnknownHostException e) { | ||
| throw new IllegalArgumentException("Invalid IP address: " + addressPart, e); | ||
| } | ||
|
|
||
| this.addressLength = rawAddress.length; | ||
|
|
||
| // Validate prefix length | ||
| int maxPrefixLength = addressLength * 8; // converts address length to bits | ||
| if (prefixLength < 0 || prefixLength > maxPrefixLength) { | ||
| throw new IllegalArgumentException( | ||
| "Invalid prefix length " + prefixLength + " for address type (must be 0-" + maxPrefixLength + ")" | ||
| ); | ||
| } | ||
|
|
||
| // Apply the mask to the network address to normalize it | ||
| this.networkAddress = applyMask(rawAddress); | ||
| } | ||
|
|
||
| /** | ||
| * Tests whether the given socket address belongs to this subnet. | ||
| * | ||
| * @param socketAddress the socket address to test | ||
| * @return true if the address is in this subnet, false otherwise | ||
| */ | ||
| @Override | ||
| public boolean test(InetSocketAddress socketAddress) { | ||
cthirouin-swi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if (socketAddress == null) { | ||
| return false; | ||
| } | ||
|
|
||
| InetAddress address = socketAddress.getAddress(); | ||
| if (address == null) { | ||
| return false; | ||
| } | ||
bplessis-swi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| byte[] testAddress = address.getAddress(); | ||
|
|
||
| // Different address families don't match | ||
| if (testAddress.length != addressLength) { | ||
| return false; | ||
| } | ||
|
|
||
| byte[] maskedTestAddress = applyMask(testAddress); | ||
|
|
||
| // Compare network portions | ||
| for (int i = 0; i < networkAddress.length; i++) { | ||
| if (networkAddress[i] != maskedTestAddress[i]) { | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| /** | ||
| * Applies a subnet mask to an IP address. | ||
| * | ||
| * @param address the raw IP address bytes | ||
| * @return the masked address bytes | ||
| */ | ||
| private byte[] applyMask(byte[] address) { | ||
| byte[] result = new byte[address.length]; | ||
|
|
||
| int fullBytes = prefixLength / 8; | ||
| int remainingBits = prefixLength % 8; | ||
|
|
||
| // Copy the full bytes | ||
| System.arraycopy(address, 0, result, 0, fullBytes); | ||
|
|
||
| // Apply mask to the partial byte if any | ||
| if (remainingBits > 0) { | ||
| int mask = 0xFF << (8 - remainingBits); | ||
| result[fullBytes] = (byte) (address[fullBytes] & mask); | ||
| } | ||
|
|
||
| // Remaining bytes are already 0 | ||
| return result; | ||
| } | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| try { | ||
| InetAddress addr = InetAddress.getByAddress(networkAddress); | ||
| return addr.getHostAddress() + "/" + prefixLength; | ||
| } catch (UnknownHostException e) { | ||
| return "SubnetPredicate[invalid]"; | ||
| } | ||
| } | ||
| } | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 3 additions & 3 deletions
6
...ket-core/src/test/java/net/airvantage/proxysocket/core/v2/ProxyProtocolV2DecoderTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 3 additions & 3 deletions
6
proxy-socket-core/src/test/java/net/airvantage/proxysocket/core/v2/ProxyProtocolV2Test.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.