Skip to content

Commit 7f29689

Browse files
committed
Avoid unnecessary buffer copies & allocates in NIO
1 parent a643269 commit 7f29689

File tree

3 files changed

+17
-24
lines changed

3 files changed

+17
-24
lines changed

app/src/main/java/tech/httptoolkit/android/vpn/capture/SOCKS5Handler.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,6 @@ public void confirmHandshakeDataWritten() {
7676

7777
@Override
7878
public void processHandshakeData(ByteBuffer data) {
79-
ByteBuffer view = data.asReadOnlyBuffer();
80-
byte[] bytes = new byte[view.remaining()];
81-
view.get(bytes);
82-
8379
switch (socksState) {
8480
case AUTH_REQUEST_PENDING:
8581
if (SOCKS5Protocol.parseAuthResponse(data)) {

app/src/main/java/tech/httptoolkit/android/vpn/socket/SocketChannelReader.java

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ class SocketChannelReader {
3939

4040
private final ClientPacketWriter writer;
4141

42+
// We're single-threaded, so we can just reuse a single max-size buffer
43+
// over and over instead of endlessly reallocating it.
44+
private final ByteBuffer readBuffer = ByteBuffer.allocate(DataConst.MAX_RECEIVE_BUFFER_SIZE);
45+
4246
public SocketChannelReader(ClientPacketWriter writer) {
4347
this.writer = writer;
4448
}
@@ -89,17 +93,16 @@ private void readTCP(@NonNull Session session) {
8993
}
9094

9195
SocketChannel channel = (SocketChannel) session.getChannel();
92-
ByteBuffer buffer = ByteBuffer.allocate(DataConst.MAX_RECEIVE_BUFFER_SIZE);
9396
int len;
9497

9598
try {
9699
do {
97-
len = channel.read(buffer);
100+
len = channel.read(readBuffer);
98101
if (len > 0) { //-1 mean it reach the end of stream
99-
buffer.limit(len);
100-
buffer.flip();
101-
sendToRequester(buffer, session);
102-
buffer.clear();
102+
readBuffer.limit(len);
103+
readBuffer.flip();
104+
sendToRequester(readBuffer, session);
105+
readBuffer.clear();
103106
} else if (len == -1) {
104107
Log.d(TAG,"End of data from remote server, will send FIN to client");
105108
Log.d(TAG,"send FIN to: " + session);
@@ -206,7 +209,6 @@ private void sendFin(Session session){
206209

207210
private void readUDP(Session session){
208211
DatagramChannel channel = (DatagramChannel) session.getChannel();
209-
ByteBuffer buffer = ByteBuffer.allocate(DataConst.MAX_RECEIVE_BUFFER_SIZE);
210212
int len;
211213

212214
try {
@@ -215,23 +217,21 @@ private void readUDP(Session session){
215217
break;
216218
}
217219

218-
len = channel.read(buffer);
220+
len = channel.read(readBuffer);
219221
if (len > 0) {
220-
buffer.limit(len);
221-
buffer.flip();
222+
readBuffer.limit(len);
223+
readBuffer.flip();
222224

223225
//create UDP packet
224-
byte[] data = new byte[len];
225-
System.arraycopy(buffer.array(),0, data, 0, len);
226226
byte[] packetData = UDPPacketFactory.createResponsePacket(
227-
session.getLastIpHeader(), session.getLastUdpHeader(), data);
227+
session.getLastIpHeader(), session.getLastUdpHeader(), readBuffer);
228+
readBuffer.clear();
228229

229230
//write to client
230231
writer.write(packetData);
231232

232233
Log.d(TAG,"SDR: sent " + len + " bytes to UDP client, packetData.length: "
233234
+ packetData.length);
234-
buffer.clear();
235235
}
236236
} while(len > 0);
237237
}catch(NotYetConnectedException ex){

app/src/main/java/tech/httptoolkit/android/vpn/transport/udp/UDPPacketFactory.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,10 @@ public static UDPHeader copyHeader(UDPHeader header){
3434
* @param packetData packet data to be sent to client
3535
* @return array of byte
3636
*/
37-
public static byte[] createResponsePacket(IPv4Header ip, UDPHeader udp, byte[] packetData){
37+
public static byte[] createResponsePacket(IPv4Header ip, UDPHeader udp, ByteBuffer packetData){
3838
byte[] buffer;
3939
int udpLen = 8;
40-
if(packetData != null){
41-
udpLen += packetData.length;
42-
}
40+
udpLen += packetData.remaining();
4341
int srcPort = udp.getDestinationPort();
4442
int destPort = udp.getSourcePort();
4543
short checksum = 0;
@@ -90,8 +88,7 @@ public static byte[] createResponsePacket(IPv4Header ip, UDPHeader udp, byte[] p
9088
start += 2;
9189

9290
//now copy udp data
93-
if (packetData != null)
94-
System.arraycopy(packetData, 0, buffer, start, packetData.length);
91+
packetData.get(buffer, start, packetData.remaining());
9592

9693
return buffer;
9794
}

0 commit comments

Comments
 (0)