diff --git a/DEVELOP.md b/DEVELOP.md
index 77ae5ccd..4d426558 100644
--- a/DEVELOP.md
+++ b/DEVELOP.md
@@ -133,9 +133,7 @@ The client is an _Android_ project located in [`app/`](app/).
The [`VpnService`] is implemented by [`GnirehtetService`].
-We control the application through broadcasts received by
-[`GnirehtetControlReceiver`] (we cannot send intents to `GnirehtetService`
-directly, read comments in [`GnirehtetControlReceiver`]).
+We control the application through intents to [`GnirehtetActivity`].
Some configuration options may be passed as extra parameters, converted to a
[`VpnConfiguration`] instance. Currently, the user can configure the DNS servers
@@ -158,7 +156,7 @@ of [`IPPacketOutputStream`].
[`VpnService`]: https://developer.android.com/reference/android/net/VpnService.html
[`GnirehtetService`]: app/src/main/java/com/genymobile/gnirehtet/GnirehtetService.java
-[`GnirehtetControlReceiver`]: app/src/main/java/com/genymobile/gnirehtet/GnirehtetControlReceiver.java
+[`GnirehtetActivity`]: app/src/main/java/com/genymobile/gnirehtet/GnirehtetActivity.java
[`VpnConfiguration`]: app/src/main/java/com/genymobile/gnirehtet/VpnConfiguration.java
[`startActivityForResult`]: https://developer.android.com/reference/android/app/Activity.html#startActivityForResult%28android.content.Intent,%20int%29
[`Activity`]: https://developer.android.com/reference/android/app/Activity.html
diff --git a/README.md b/README.md
index ba08dce6..d4ec165d 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Gnirehtet (v2.3)
+# Gnirehtet (v2.5)
This project provides **reverse tethering** over `adb` for Android: it
allows devices to use the internet connection of the computer they are plugged
@@ -64,24 +64,36 @@ Make sure you [enabled adb debugging][enable-adb] on your device(s).
[platform-tools-windows]: https://dl.google.com/android/repository/platform-tools-latest-windows.zip
-## Download
+## Get the app
+
+### Homebrew
+
+If you use [Homebrew](https://brew.sh/), getting up and running is very quick.
+To install the Rust version:
+
+```
+brew install gnirehtet
+```
+
+### Download
Download the [latest release][latest] in the flavor you want.
[latest]: https://github.com/Genymobile/gnirehtet/releases/latest
-### Rust
- - **Linux:** [`gnirehtet-rust-linux64-v2.3.zip`][direct-rust-linux64]
- (SHA-256: _561d77e94d65ecf2d919053e5da6109b8cceb73bffedea71cd4e51304ccaa3d3_)
- - **Windows:** [`gnirehtet-rust-win64-v2.3.zip`][direct-rust-win64]
- (SHA-256: _4c4d961f069a663d6b826f24a8795d1752f3e316f121d2bfc296a4cd32c8d4ca_)
+#### Rust
+
+ - **Linux:** [`gnirehtet-rust-linux64-v2.5.zip`][direct-rust-linux64]
+ (SHA-256: _2b1ce04540e8de5df5ddbebb64bb01e27c13d556b3a04a8563dcce3786765705_)
+ - **Windows:** [`gnirehtet-rust-win64-v2.5.zip`][direct-rust-win64]
+ (SHA-256: _9f6d7700368f45d2fa43923324660eca9f879e837e10fc45d8d975273eae4755_)
- **MacOS:** [`gnirehtet-rust-macos64-v2.2.1.zip`][direct-rust-macos64]
- _(previous release)_
+ _(old release)_
(SHA-256: _902103e6497f995e1e9b92421be212559950cca4a8b557e1f0403769aee06fc8_)
-[direct-rust-linux64]: https://github.com/Genymobile/gnirehtet/releases/download/v2.3/gnirehtet-rust-linux64-v2.3.zip
-[direct-rust-win64]: https://github.com/Genymobile/gnirehtet/releases/download/v2.3/gnirehtet-rust-win64-v2.3.zip
+[direct-rust-linux64]: https://github.com/Genymobile/gnirehtet/releases/download/v2.5/gnirehtet-rust-linux64-v2.5.zip
+[direct-rust-win64]: https://github.com/Genymobile/gnirehtet/releases/download/v2.5/gnirehtet-rust-win64-v2.5.zip
[direct-rust-macos64]: https://github.com/Genymobile/gnirehtet/releases/download/v2.2.1/gnirehtet-rust-macos64-v2.2.1.zip
Then extract it.
@@ -96,12 +108,12 @@ The Windows archive contains:
- `gnirehtet-run.cmd`
-### Java
+#### Java
- - **All platforms:** [`gnirehtet-java-v2.3.zip`][direct-java]
- (SHA-256: _93d1d46ee566376596f033832626dd5e89e76c91f2c46d2383735937b7d3b8b0_)
+ - **All platforms:** [`gnirehtet-java-v2.5.zip`][direct-java]
+ (SHA-256: _c65fc1a35e6b169ab6aa45e695c043e933f6fd650363aea7c2add0ecb0db27ca_)
-[direct-java]: https://github.com/Genymobile/gnirehtet/releases/download/v2.3/gnirehtet-java-v2.3.zip
+[direct-java]: https://github.com/Genymobile/gnirehtet/releases/download/v2.5/gnirehtet-java-v2.5.zip
Then extract it. The archive contains:
- `gnirehtet.apk`
@@ -182,7 +194,7 @@ lower-level commands. You can call them manually instead.
To start the relay server:
- java -jar gnirehtet.jar relay
+ ./gnirehtet relay
To install the apk:
@@ -191,13 +203,28 @@ To install the apk:
To start a client:
adb reverse localabstract:gnirehtet tcp:31416
- adb shell am broadcast -a com.genymobile.gnirehtet.START \
- -n com.genymobile.gnirehtet/.GnirehtetControlReceiver
+ adb shell am start -a com.genymobile.gnirehtet.START \
+ -n com.genymobile.gnirehtet/.GnirehtetActivity
To stop a client:
- adb shell am broadcast -a com.genymobile.gnirehtet.STOP \
- -n com.genymobile.gnirehtet/.GnirehtetControlReceiver
+ adb shell am start -a com.genymobile.gnirehtet.STOP \
+ -n com.genymobile.gnirehtet/.GnirehtetActivity
+
+
+## Environment variables
+
+`ADB` defines a custom path to the `adb` executable:
+
+```bash
+ADB=/path/to/my/adb ./gnirehtet run
+```
+
+`GNIREHTET_APK` defines a custom path to `gnirehtet.apk`:
+
+```bash
+GNIREHTET_APK=/usr/share/gnirehtet/gnirehtet.apk ./gnirehtet run
+```
## Why _gnirehtet_?
diff --git a/app/build.gradle b/app/build.gradle
index 0910e052..1f02e889 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -8,9 +8,9 @@ android {
archivesBaseName = "gnirehtet" // change apk name
applicationId "com.genymobile.gnirehtet"
minSdkVersion 21
- targetSdkVersion 28
- versionCode 6
- versionName "2.3"
+ targetSdkVersion 29
+ versionCode 8
+ versionName "2.5"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
diff --git a/app/local.properties b/app/local.properties
new file mode 100644
index 00000000..c82f585e
--- /dev/null
+++ b/app/local.properties
@@ -0,0 +1,8 @@
+## This file must *NOT* be checked into Version Control Systems,
+# as it contains information specific to your local configuration.
+#
+# Location of the SDK. This is only used by Gradle.
+# For customization when using a Version Control System, please read the
+# header note.
+#Thu Jul 01 13:56:53 MSK 2021
+sdk.dir=C\:\\Users\\barto\\AppData\\Local\\Android\\Sdk
diff --git a/app/release/gnirehtet.apk b/app/release/gnirehtet.apk
new file mode 100644
index 00000000..fbb6ea06
Binary files /dev/null and b/app/release/gnirehtet.apk differ
diff --git a/app/release/output.json b/app/release/output.json
new file mode 100644
index 00000000..16680caf
--- /dev/null
+++ b/app/release/output.json
@@ -0,0 +1 @@
+[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":8,"versionName":"2.5","enabled":true,"outputFile":"gnirehtet-release.apk","fullName":"release","baseName":"release"},"path":"gnirehtet-release.apk","properties":{}}]
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c0a59744..c96fe049 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,10 +1,11 @@
+ xmlns:tools="http://schemas.android.com/tools"
+ package="com.genymobile.gnirehtet">
-
+
+
+
+
+
+
+
+
-
-
+
-
-
\ No newline at end of file
diff --git a/app/src/main/java/com/genymobile/gnirehtet/AuthorizationActivity.java b/app/src/main/java/com/genymobile/gnirehtet/AuthorizationActivity.java
deleted file mode 100644
index f1153979..00000000
--- a/app/src/main/java/com/genymobile/gnirehtet/AuthorizationActivity.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2017 Genymobile
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.genymobile.gnirehtet;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-
-public class AuthorizationActivity extends Activity {
-
- public static final String EXTRA_VPN_INTENT = "com.genymobile.gnirehtet.VPN_INTENT";
- public static final String EXTRA_VPN_CONFIGURATION = "vpnConfiguration";
-
- private static final int VPN_REQUEST_CODE = 0;
-
- private VpnConfiguration config;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- Intent intent = getIntent();
- Intent vpnIntent = intent.getParcelableExtra(EXTRA_VPN_INTENT);
- config = intent.getParcelableExtra(EXTRA_VPN_CONFIGURATION);
- startActivityForResult(vpnIntent, VPN_REQUEST_CODE);
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if (requestCode == VPN_REQUEST_CODE && resultCode == RESULT_OK) {
- GnirehtetService.start(this, config);
- }
- finish();
- }
-}
diff --git a/app/src/main/java/com/genymobile/gnirehtet/Binary.java b/app/src/main/java/com/genymobile/gnirehtet/Binary.java
index faec6138..ae0603d9 100644
--- a/app/src/main/java/com/genymobile/gnirehtet/Binary.java
+++ b/app/src/main/java/com/genymobile/gnirehtet/Binary.java
@@ -19,6 +19,8 @@
@SuppressWarnings("checkstyle:MagicNumber")
public final class Binary {
+ private static final int MAX_STRING_PACKET_SIZE = 20;
+
private Binary() {
// not instantiable
}
@@ -35,15 +37,20 @@ public static long unsigned(int value) {
return value & 0xffffffffL;
}
- public static String toString(byte[] data, int len) {
+ public static String buildPacketString(byte[] data, int len) {
+ int limit = Math.min(MAX_STRING_PACKET_SIZE, len);
StringBuilder builder = new StringBuilder();
- for (int i = 0; i < len; ++i) {
- if (i % 8 == 0) {
- builder.append('\n');
+ builder.append('[').append(len).append(" bytes] ");
+ for (int i = 0; i < limit; ++i) {
+ if (i != 0) {
+ String sep = i % 4 == 0 ? " " : " ";
+ builder.append(sep);
}
- builder.append(String.format("%02X ", data[i] & 0xff));
+ builder.append(String.format("%02X", data[i] & 0xff));
+ }
+ if (limit < len) {
+ builder.append(" ... +").append(len - limit).append(" bytes");
}
return builder.toString();
}
-
}
diff --git a/app/src/main/java/com/genymobile/gnirehtet/Forwarder.java b/app/src/main/java/com/genymobile/gnirehtet/Forwarder.java
index 0f50d9d8..61b9a16b 100644
--- a/app/src/main/java/com/genymobile/gnirehtet/Forwarder.java
+++ b/app/src/main/java/com/genymobile/gnirehtet/Forwarder.java
@@ -37,7 +37,7 @@ public class Forwarder {
private static final String TAG = Forwarder.class.getSimpleName();
- private static final int BUFSIZE = 4096;
+ private static final int BUFSIZE = 0x10000;
private static final byte[] DUMMY_ADDRESS = {42, 42, 42, 42};
private static final int DUMMY_PORT = 4242;
@@ -129,9 +129,6 @@ private void forwardTunnelToDevice(Tunnel tunnel) throws IOException {
break;
}
if (w > 0) {
- if (GnirehtetService.VERBOSE) {
- Log.d(TAG, "WRITING " + w + "..." + Binary.toString(buffer, w));
- }
// blocking write
packetOutputStream.write(buffer, 0, w);
} else {
diff --git a/app/src/main/java/com/genymobile/gnirehtet/GnirehtetActivity.java b/app/src/main/java/com/genymobile/gnirehtet/GnirehtetActivity.java
new file mode 100644
index 00000000..b34885e8
--- /dev/null
+++ b/app/src/main/java/com/genymobile/gnirehtet/GnirehtetActivity.java
@@ -0,0 +1,97 @@
+package com.genymobile.gnirehtet;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.net.VpnService;
+import android.os.Bundle;
+import android.util.Log;
+
+/**
+ * This (invisible) activity receives the {@link #ACTION_GNIREHTET_START START} and
+ * {@link #ACTION_GNIREHTET_STOP} actions from the command line.
+ *
+ * Recent versions of Android refuse to directly start a {@link android.app.Service Service} or a
+ * {@link android.content.BroadcastReceiver BroadcastReceiver}, so actions are always managed by
+ * this activity.
+ */
+public class GnirehtetActivity extends Activity {
+
+ private static final String TAG = GnirehtetActivity.class.getSimpleName();
+
+ public static final String ACTION_GNIREHTET_START = "com.genymobile.gnirehtet.START";
+ public static final String ACTION_GNIREHTET_STOP = "com.genymobile.gnirehtet.STOP";
+
+ public static final String EXTRA_DNS_SERVERS = "dnsServers";
+ public static final String EXTRA_ROUTES = "routes";
+
+ private static final int VPN_REQUEST_CODE = 0;
+
+ private VpnConfiguration requestedConfig;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ handleIntent(getIntent());
+ }
+
+ private void handleIntent(Intent intent) {
+ String action = intent.getAction();
+ Log.d(TAG, "Received request " + action);
+ boolean finish = true;
+ if (ACTION_GNIREHTET_START.equals(action)) {
+ VpnConfiguration config = createConfig(intent);
+ finish = startGnirehtet(config);
+ } else if (ACTION_GNIREHTET_STOP.equals(action)) {
+ stopGnirehtet();
+ }
+
+ if (finish) {
+ finish();
+ }
+ }
+
+ private static VpnConfiguration createConfig(Intent intent) {
+ String[] dnsServers = intent.getStringArrayExtra(EXTRA_DNS_SERVERS);
+ if (dnsServers == null) {
+ dnsServers = new String[0];
+ }
+ String[] routes = intent.getStringArrayExtra(EXTRA_ROUTES);
+ if (routes == null) {
+ routes = new String[0];
+ }
+ return new VpnConfiguration(Net.toInetAddresses(dnsServers), Net.toCIDRs(routes));
+ }
+
+ private boolean startGnirehtet(VpnConfiguration config) {
+ Intent vpnIntent = VpnService.prepare(this);
+ if (vpnIntent == null) {
+ Log.d(TAG, "VPN was already authorized");
+ // we got the permission, start the service now
+ GnirehtetService.start(this, config);
+ return true;
+ }
+
+ Log.w(TAG, "VPN requires the authorization from the user, requesting...");
+ requestAuthorization(vpnIntent, config);
+ return false; // do not finish now
+ }
+
+ private void stopGnirehtet() {
+ GnirehtetService.stop(this);
+ }
+
+ private void requestAuthorization(Intent vpnIntent, VpnConfiguration config) {
+ requestedConfig = config;
+ startActivityForResult(vpnIntent, VPN_REQUEST_CODE);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if (requestCode == VPN_REQUEST_CODE && resultCode == RESULT_OK) {
+ GnirehtetService.start(this, requestedConfig);
+ }
+ requestedConfig = null;
+ finish();
+ }
+}
diff --git a/app/src/main/java/com/genymobile/gnirehtet/GnirehtetControlReceiver.java b/app/src/main/java/com/genymobile/gnirehtet/GnirehtetControlReceiver.java
index 04379516..23f81b73 100644
--- a/app/src/main/java/com/genymobile/gnirehtet/GnirehtetControlReceiver.java
+++ b/app/src/main/java/com/genymobile/gnirehtet/GnirehtetControlReceiver.java
@@ -1,92 +1,23 @@
-/*
- * Copyright (C) 2017 Genymobile
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
package com.genymobile.gnirehtet;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-import android.net.VpnService;
import android.util.Log;
-import static com.genymobile.gnirehtet.AuthorizationActivity.EXTRA_VPN_CONFIGURATION;
-
-/**
- * Receiver to expose {@link #ACTION_GNIREHTET_START START} and {@link #ACTION_GNIREHTET_STOP}
- * actions.
- *
- * Since {@link GnirehtetService} extends {@link VpnService}, it requires the clients to have the
- * system permission {@code android.permission.BIND_VPN_SERVICE}, which {@code shell} have not. As a
- * consequence, we cannot expose our own actions intended to be called from {@code shell} directly
- * in {@link GnirehtetService}.
- *
- * Starting the VPN requires authorization from the user. If the authorization is not granted yet,
- * an {@code Intent}, returned by the system, must be sent from an Activity
- * (through {@link android.app.Activity#startActivityForResult(Intent, int)
- * startActivityForResult()}. However, if the authorization is already granted, it is better to
- * avoid starting an {@link android.app.Activity Activity} (which would be useless), since it may
- * cause (minor) side effects (like closing any open virtual keyboard). Therefore, this {@link
- * GnirehtetControlReceiver} starts an {@link android.app.Activity Activity} only when necessary.
- *
- * Stopping the VPN just consists in delegating the request to {@link GnirehtetService} (which is
- * accessible from here).
- */
public class GnirehtetControlReceiver extends BroadcastReceiver {
-
- public static final String ACTION_GNIREHTET_START = "com.genymobile.gnirehtet.START";
- public static final String ACTION_GNIREHTET_STOP = "com.genymobile.gnirehtet.STOP";
-
- public static final String EXTRA_DNS_SERVERS = "dnsServers";
- public static final String EXTRA_ROUTES = "routes";
-
private static final String TAG = GnirehtetControlReceiver.class.getSimpleName();
-
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, "Received request " + action);
- if (ACTION_GNIREHTET_START.equals(action)) {
- VpnConfiguration config = createConfig(intent);
- startGnirehtet(context, config);
- } else if (ACTION_GNIREHTET_STOP.equals(action)) {
- stopGnirehtet(context);
- }
- }
-
- private static VpnConfiguration createConfig(Intent intent) {
- String[] dnsServers = intent.getStringArrayExtra(EXTRA_DNS_SERVERS);
- if (dnsServers == null) {
- dnsServers = new String[0];
- }
- String[] routes = intent.getStringArrayExtra(EXTRA_ROUTES);
- if (routes == null) {
- routes = new String[0];
- }
- return new VpnConfiguration(Net.toInetAddresses(dnsServers), Net.toCIDRs(routes));
- }
-
- private void startGnirehtet(Context context, VpnConfiguration config) {
- Intent vpnIntent = VpnService.prepare(context);
- if (vpnIntent == null) {
- Log.d(TAG, "VPN was already authorized");
- // we got the permission, start the service now
- GnirehtetService.start(context, config);
- } else {
- Log.w(TAG, "VPN requires the authorization from the user, requesting...");
- requestAuthorization(context, vpnIntent, config);
+ if ("android.hardware.usb.action.USB_STATE".equals(action)) {
+ if (intent.getExtras().getBoolean("connected")) {
+ // USB was connected
+ } else {
+ // USB was disconnected
+ stopGnirehtet(context);
+ }
}
}
@@ -94,12 +25,4 @@ private void stopGnirehtet(Context context) {
GnirehtetService.stop(context);
}
- private void requestAuthorization(Context context, Intent vpnIntent, VpnConfiguration config) {
- // we must send the intent with startActivityForResult, so we need to send it from an activity
- Intent intent = new Intent(context, AuthorizationActivity.class);
- intent.putExtra(AuthorizationActivity.EXTRA_VPN_INTENT, vpnIntent);
- intent.putExtra(EXTRA_VPN_CONFIGURATION, config);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- context.startActivity(intent);
- }
}
diff --git a/app/src/main/java/com/genymobile/gnirehtet/GnirehtetService.java b/app/src/main/java/com/genymobile/gnirehtet/GnirehtetService.java
index 7e8b716e..7ec55a56 100644
--- a/app/src/main/java/com/genymobile/gnirehtet/GnirehtetService.java
+++ b/app/src/main/java/com/genymobile/gnirehtet/GnirehtetService.java
@@ -225,6 +225,7 @@ public void handleMessage(Message message) {
case RelayTunnelListener.MSG_RELAY_TUNNEL_DISCONNECTED:
Log.d(TAG, "Relay tunnel disconnected");
vpnService.notifier.setFailure(true);
+ vpnService.stop(vpnService);
break;
default:
}
diff --git a/app/src/main/java/com/genymobile/gnirehtet/Notifier.java b/app/src/main/java/com/genymobile/gnirehtet/Notifier.java
index eb1bdf40..a83561cd 100644
--- a/app/src/main/java/com/genymobile/gnirehtet/Notifier.java
+++ b/app/src/main/java/com/genymobile/gnirehtet/Notifier.java
@@ -20,7 +20,6 @@ public class Notifier {
private final Service context;
private boolean failure;
-
public Notifier(Service context) {
this.context = context;
}
@@ -35,7 +34,6 @@ private Notification createNotification(boolean failure) {
notificationBuilder.setContentText(context.getString(R.string.relay_connected));
notificationBuilder.setSmallIcon(R.drawable.ic_usb_24dp);
}
- notificationBuilder.addAction(createStopAction());
return notificationBuilder.build();
}
@@ -64,7 +62,7 @@ public void start() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createNotificationChannel();
}
- context.startForeground(NOTIFICATION_ID, createNotification(false));
+ context.startForeground(NOTIFICATION_ID, createNotification(failure));
}
public void stop() {
@@ -82,16 +80,6 @@ public void setFailure(boolean failure) {
}
}
- private Notification.Action createStopAction() {
- Intent stopIntent = GnirehtetService.createStopIntent(context);
- PendingIntent stopPendingIntent = PendingIntent.getService(context, 0, stopIntent, PendingIntent.FLAG_ONE_SHOT);
- // the non-deprecated constructor is not available in API 21
- @SuppressWarnings("deprecation")
- Notification.Action.Builder actionBuilder = new Notification.Action.Builder(R.drawable.ic_close_24dp, context.getString(R.string.stop_vpn),
- stopPendingIntent);
- return actionBuilder.build();
- }
-
private NotificationManager getNotificationManager() {
return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
}
diff --git a/app/src/main/java/com/genymobile/gnirehtet/RelayTunnel.java b/app/src/main/java/com/genymobile/gnirehtet/RelayTunnel.java
index a0b09af0..51aa436f 100644
--- a/app/src/main/java/com/genymobile/gnirehtet/RelayTunnel.java
+++ b/app/src/main/java/com/genymobile/gnirehtet/RelayTunnel.java
@@ -76,7 +76,7 @@ private static void readClientId(InputStream inputStream) throws IOException {
@Override
public void send(byte[] packet, int len) throws IOException {
if (GnirehtetService.VERBOSE) {
- Log.d(TAG, "Sending..." + Binary.toString(packet, len));
+ Log.v(TAG, "Sending packet: " + Binary.buildPacketString(packet, len));
}
localSocket.getOutputStream().write(packet, 0, len);
}
@@ -85,7 +85,7 @@ public void send(byte[] packet, int len) throws IOException {
public int receive(byte[] packet) throws IOException {
int r = localSocket.getInputStream().read(packet);
if (GnirehtetService.VERBOSE) {
- Log.d(TAG, "Receiving..." + Binary.toString(packet, r));
+ Log.v(TAG, "Receiving packet: " + Binary.buildPacketString(packet, r));
}
return r;
}
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index e68b4351..a6acd6aa 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -2,5 +2,4 @@
Reverse tethering activé
Déconnecté du serveur relais
- Arrêter Gnirehtet
\ No newline at end of file
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
new file mode 100644
index 00000000..7d67c4e6
--- /dev/null
+++ b/app/src/main/res/values-ru/strings.xml
@@ -0,0 +1,5 @@
+
+
+ Передача по USB активирована
+ Передача по USB отключена
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 7ffac67a..e0bc6eac 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -2,5 +2,4 @@
Gnirehtet
Reverse tethering enabled
Disconnected from the relay server
- Stop Gnirehtet
diff --git a/build.gradle b/build.gradle
index 2f9b032e..e87852c0 100644
--- a/build.gradle
+++ b/build.gradle
@@ -11,7 +11,7 @@ buildscript {
google()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.2.1'
+ classpath 'com.android.tools.build:gradle:3.5.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 1fdfe3c6..b81e6d75 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Sat Jan 20 13:10:05 CET 2018
+#Sat Sep 07 21:43:49 CEST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.10-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
diff --git a/relay-java/src/main/java/com/genymobile/gnirehtet/CommandLineArguments.java b/relay-java/src/main/java/com/genymobile/gnirehtet/CommandLineArguments.java
index aca58edb..6413d0c8 100644
--- a/relay-java/src/main/java/com/genymobile/gnirehtet/CommandLineArguments.java
+++ b/relay-java/src/main/java/com/genymobile/gnirehtet/CommandLineArguments.java
@@ -19,13 +19,18 @@
/**
* Simple specific command-line arguments parser.
*/
+@SuppressWarnings("checkstyle:MagicNumber")
public class CommandLineArguments {
public static final int PARAM_NONE = 0;
public static final int PARAM_SERIAL = 1;
public static final int PARAM_DNS_SERVER = 1 << 1;
public static final int PARAM_ROUTES = 1 << 2;
+ public static final int PARAM_PORT = 1 << 3;
+ public static final int DEFAULT_PORT = 31416;
+
+ private int port;
private String serial;
private String dnsServers;
private String routes;
@@ -52,12 +57,27 @@ public static CommandLineArguments parse(int acceptedParameters, String... args)
}
arguments.routes = args[i + 1];
++i; // consume the -r parameter
+ } else if ((acceptedParameters & PARAM_PORT) != 0 && "-p".equals(arg)) {
+ if (arguments.port != 0) {
+ throw new IllegalArgumentException("Port already set");
+ }
+ if (i == args.length - 1) {
+ throw new IllegalArgumentException("Missing -p parameter");
+ }
+ arguments.port = Integer.parseInt(args[i + 1]);
+ if (arguments.port <= 0 || arguments.port >= 65536) {
+ throw new IllegalArgumentException("Invalid port: " + arguments.port);
+ }
+ ++i;
} else if ((acceptedParameters & PARAM_SERIAL) != 0 && arguments.serial == null) {
arguments.serial = arg;
} else {
throw new IllegalArgumentException("Unexpected argument: \"" + arg + "\"");
}
}
+ if (arguments.port == 0) {
+ arguments.port = DEFAULT_PORT;
+ }
return arguments;
}
@@ -72,4 +92,8 @@ public String getDnsServers() {
public String getRoutes() {
return routes;
}
+
+ public int getPort() {
+ return port;
+ }
}
diff --git a/relay-java/src/main/java/com/genymobile/gnirehtet/Main.java b/relay-java/src/main/java/com/genymobile/gnirehtet/Main.java
index 25bf68bf..03b6efcb 100644
--- a/relay-java/src/main/java/com/genymobile/gnirehtet/Main.java
+++ b/relay-java/src/main/java/com/genymobile/gnirehtet/Main.java
@@ -32,12 +32,22 @@
public final class Main {
private static final String TAG = "Gnirehtet";
private static final String NL = System.lineSeparator();
- private static final String REQUIRED_APK_VERSION_CODE = "6";
+ private static final String REQUIRED_APK_VERSION_CODE = "8";
private Main() {
// not instantiable
}
+ private static String getAdbPath() {
+ String adb = System.getenv("ADB");
+ return adb != null ? adb : "adb";
+ }
+
+ private static String getApkPath() {
+ String apk = System.getenv("GNIREHTET_APK");
+ return apk != null ? apk : "gnirehtet.apk";
+ }
+
enum Command {
INSTALL("install", CommandLineArguments.PARAM_SERIAL) {
@Override
@@ -76,7 +86,8 @@ void execute(CommandLineArguments args) throws Exception {
cmdReinstall(args.getSerial());
}
},
- RUN("run", CommandLineArguments.PARAM_SERIAL | CommandLineArguments.PARAM_DNS_SERVER | CommandLineArguments.PARAM_ROUTES) {
+ RUN("run", CommandLineArguments.PARAM_SERIAL | CommandLineArguments.PARAM_DNS_SERVER | CommandLineArguments.PARAM_ROUTES
+ | CommandLineArguments.PARAM_PORT) {
@Override
String getDescription() {
return "Enable reverse tethering for exactly one device:\n"
@@ -88,10 +99,10 @@ String getDescription() {
@Override
void execute(CommandLineArguments args) throws Exception {
- cmdRun(args.getSerial(), args.getDnsServers(), args.getRoutes());
+ cmdRun(args.getSerial(), args.getDnsServers(), args.getRoutes(), args.getPort());
}
},
- AUTORUN("autorun", CommandLineArguments.PARAM_DNS_SERVER | CommandLineArguments.PARAM_ROUTES) {
+ AUTORUN("autorun", CommandLineArguments.PARAM_DNS_SERVER | CommandLineArguments.PARAM_ROUTES | CommandLineArguments.PARAM_PORT) {
@Override
String getDescription() {
return "Enable reverse tethering for all devices:\n"
@@ -101,10 +112,11 @@ String getDescription() {
@Override
void execute(CommandLineArguments args) throws Exception {
- cmdAutorun(args.getDnsServers(), args.getRoutes());
+ cmdAutorun(args.getDnsServers(), args.getRoutes(), args.getPort());
}
},
- START("start", CommandLineArguments.PARAM_SERIAL | CommandLineArguments.PARAM_DNS_SERVER | CommandLineArguments.PARAM_ROUTES) {
+ START("start", CommandLineArguments.PARAM_SERIAL | CommandLineArguments.PARAM_DNS_SERVER | CommandLineArguments.PARAM_ROUTES
+ | CommandLineArguments.PARAM_PORT) {
@Override
String getDescription() {
return "Start a client on the Android device and exit.\n"
@@ -113,6 +125,8 @@ String getDescription() {
+ "If -d is given, then make the Android device use the specified\n"
+ "DNS server(s). Otherwise, use 8.8.8.8 (Google public DNS).\n"
+ "If -r is given, then only reverse tether the specified routes.\n"
+ + "If -p is given, then make the relay server listen on the specified\n"
+ + "port. Otherwise, use port 31416.\n"
+ "Otherwise, use 0.0.0.0/0 (redirect the whole traffic).\n"
+ "If the client is already started, then do nothing, and ignore\n"
+ "the other parameters.\n"
@@ -121,10 +135,10 @@ String getDescription() {
@Override
void execute(CommandLineArguments args) throws Exception {
- cmdStart(args.getSerial(), args.getDnsServers(), args.getRoutes());
+ cmdStart(args.getSerial(), args.getDnsServers(), args.getRoutes(), args.getPort());
}
},
- AUTOSTART("autostart", CommandLineArguments.PARAM_DNS_SERVER | CommandLineArguments.PARAM_ROUTES) {
+ AUTOSTART("autostart", CommandLineArguments.PARAM_DNS_SERVER | CommandLineArguments.PARAM_ROUTES | CommandLineArguments.PARAM_PORT) {
@Override
String getDescription() {
return "Listen for device connexions and start a client on every detected\n"
@@ -135,7 +149,7 @@ String getDescription() {
@Override
void execute(CommandLineArguments args) throws Exception {
- cmdAutostart(args.getDnsServers(), args.getRoutes());
+ cmdAutostart(args.getDnsServers(), args.getRoutes(), args.getPort());
}
},
STOP("stop", CommandLineArguments.PARAM_SERIAL) {
@@ -151,7 +165,8 @@ void execute(CommandLineArguments args) throws Exception {
cmdStop(args.getSerial());
}
},
- RESTART("restart", CommandLineArguments.PARAM_SERIAL | CommandLineArguments.PARAM_DNS_SERVER | CommandLineArguments.PARAM_ROUTES) {
+ RESTART("restart", CommandLineArguments.PARAM_SERIAL | CommandLineArguments.PARAM_DNS_SERVER | CommandLineArguments.PARAM_ROUTES
+ | CommandLineArguments.PARAM_PORT) {
@Override
String getDescription() {
return "Stop then start.";
@@ -159,10 +174,10 @@ String getDescription() {
@Override
void execute(CommandLineArguments args) throws Exception {
- cmdRestart(args.getSerial(), args.getDnsServers(), args.getRoutes());
+ cmdRestart(args.getSerial(), args.getDnsServers(), args.getRoutes(), args.getPort());
}
},
- TUNNEL("tunnel", CommandLineArguments.PARAM_SERIAL) {
+ TUNNEL("tunnel", CommandLineArguments.PARAM_SERIAL | CommandLineArguments.PARAM_PORT) {
@Override
String getDescription() {
return "Set up the 'adb reverse' tunnel.\n"
@@ -173,10 +188,10 @@ String getDescription() {
@Override
void execute(CommandLineArguments args) throws Exception {
- cmdTunnel(args.getSerial());
+ cmdTunnel(args.getSerial(), args.getPort());
}
},
- RELAY("relay", CommandLineArguments.PARAM_NONE) {
+ RELAY("relay", CommandLineArguments.PARAM_PORT) {
@Override
String getDescription() {
return "Start the relay server in the current terminal.";
@@ -184,7 +199,7 @@ String getDescription() {
@Override
void execute(CommandLineArguments args) throws Exception {
- cmdRelay();
+ cmdRelay(args.getPort());
}
};
@@ -203,7 +218,7 @@ void execute(CommandLineArguments args) throws Exception {
private static void cmdInstall(String serial) throws InterruptedException, IOException, CommandExecutionException {
Log.i(TAG, "Installing gnirehtet client...");
- execAdb(serial, "install", "-r", "gnirehtet.apk");
+ execAdb(serial, "install", "-r", getApkPath());
}
private static void cmdUninstall(String serial) throws InterruptedException, IOException, CommandExecutionException {
@@ -216,9 +231,9 @@ private static void cmdReinstall(String serial) throws InterruptedException, IOE
cmdInstall(serial);
}
- private static void cmdRun(String serial, String dnsServers, String routes) throws InterruptedException, IOException, CommandExecutionException {
+ private static void cmdRun(String serial, String dnsServers, String routes, int port) throws IOException {
// start in parallel so that the relay server is ready when the client connects
- asyncStart(serial, dnsServers, routes);
+ asyncStart(serial, dnsServers, routes, port);
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
// executed on Ctrl+C
@@ -229,23 +244,23 @@ private static void cmdRun(String serial, String dnsServers, String routes) thro
}
}));
- cmdRelay();
+ cmdRelay(port);
}
- private static void cmdAutorun(final String dnsServers, final String routes) throws InterruptedException, IOException, CommandExecutionException {
+ private static void cmdAutorun(final String dnsServers, final String routes, int port) throws IOException {
new Thread(() -> {
try {
- cmdAutostart(dnsServers, routes);
+ cmdAutostart(dnsServers, routes, port);
} catch (Exception e) {
Log.e(TAG, "Cannot auto start clients", e);
}
}).start();
- cmdRelay();
+ cmdRelay(port);
}
@SuppressWarnings("checkstyle:MagicNumber")
- private static void cmdStart(String serial, String dnsServers, String routes) throws InterruptedException, IOException,
+ private static void cmdStart(String serial, String dnsServers, String routes, int port) throws InterruptedException, IOException,
CommandExecutionException {
if (mustInstallClient(serial)) {
cmdInstall(serial);
@@ -254,11 +269,11 @@ private static void cmdStart(String serial, String dnsServers, String routes) th
}
Log.i(TAG, "Starting client...");
- cmdTunnel(serial);
+ cmdTunnel(serial, port);
List cmd = new ArrayList<>();
- Collections.addAll(cmd, "shell", "am", "broadcast", "-a", "com.genymobile.gnirehtet.START", "-n",
- "com.genymobile.gnirehtet/.GnirehtetControlReceiver");
+ Collections.addAll(cmd, "shell", "am", "start", "-a", "com.genymobile.gnirehtet.START", "-n",
+ "com.genymobile.gnirehtet/.GnirehtetActivity");
if (dnsServers != null) {
Collections.addAll(cmd, "--esa", "dnsServers", dnsServers);
}
@@ -268,38 +283,38 @@ private static void cmdStart(String serial, String dnsServers, String routes) th
execAdb(serial, cmd);
}
- private static void cmdAutostart(final String dnsServers, final String routes) {
+ private static void cmdAutostart(final String dnsServers, final String routes, int port) {
AdbMonitor adbMonitor = new AdbMonitor((serial) -> {
- asyncStart(serial, dnsServers, routes);
+ asyncStart(serial, dnsServers, routes, port);
});
adbMonitor.monitor();
}
private static void cmdStop(String serial) throws InterruptedException, IOException, CommandExecutionException {
Log.i(TAG, "Stopping client...");
- execAdb(serial, "shell", "am", "broadcast", "-a", "com.genymobile.gnirehtet.STOP", "-n",
- "com.genymobile.gnirehtet/.GnirehtetControlReceiver");
+ execAdb(serial, "shell", "am", "start", "-a", "com.genymobile.gnirehtet.STOP", "-n",
+ "com.genymobile.gnirehtet/.GnirehtetActivity");
}
- private static void cmdRestart(String serial, String dnsServers, String routes) throws InterruptedException, IOException,
+ private static void cmdRestart(String serial, String dnsServers, String routes, int port) throws InterruptedException, IOException,
CommandExecutionException {
cmdStop(serial);
- cmdStart(serial, dnsServers, routes);
+ cmdStart(serial, dnsServers, routes, port);
}
- private static void cmdTunnel(String serial) throws InterruptedException, IOException, CommandExecutionException {
- execAdb(serial, "reverse", "localabstract:gnirehtet", "tcp:31416");
+ private static void cmdTunnel(String serial, int port) throws InterruptedException, IOException, CommandExecutionException {
+ execAdb(serial, "reverse", "localabstract:gnirehtet", "tcp:" + port);
}
- private static void cmdRelay() throws IOException {
- Log.i(TAG, "Starting relay server...");
- new Relay().run();
+ private static void cmdRelay(int port) throws IOException {
+ Log.i(TAG, "Starting relay server on port " + port + "...");
+ new Relay(port).run();
}
- private static void asyncStart(String serial, String dnsServers, String routes) {
+ private static void asyncStart(String serial, String dnsServers, String routes, int port) {
new Thread(() -> {
try {
- cmdStart(serial, dnsServers, routes);
+ cmdStart(serial, dnsServers, routes, port);
} catch (Exception e) {
Log.e(TAG, "Cannot start client", e);
}
@@ -312,7 +327,7 @@ private static void execAdb(String serial, String... adbArgs) throws Interrupted
private static List createAdbCommand(String serial, String... adbArgs) {
List command = new ArrayList<>();
- command.add("adb");
+ command.add(getAdbPath());
if (serial != null) {
command.add("-s");
command.add(serial);
@@ -387,6 +402,9 @@ private static void appendCommandUsage(StringBuilder builder, Command command) {
if ((command.acceptedParameters & CommandLineArguments.PARAM_DNS_SERVER) != 0) {
builder.append(" [-d DNS[,DNS2,...]]");
}
+ if ((command.acceptedParameters & CommandLineArguments.PARAM_PORT) != 0) {
+ builder.append(" [-p PORT]");
+ }
if ((command.acceptedParameters & CommandLineArguments.PARAM_ROUTES) != 0) {
builder.append(" [-r ROUTE[,ROUTE2,...]]");
}
diff --git a/relay-java/src/main/java/com/genymobile/gnirehtet/relay/Binary.java b/relay-java/src/main/java/com/genymobile/gnirehtet/relay/Binary.java
index 4dd7eb61..a7b5241b 100644
--- a/relay-java/src/main/java/com/genymobile/gnirehtet/relay/Binary.java
+++ b/relay-java/src/main/java/com/genymobile/gnirehtet/relay/Binary.java
@@ -21,31 +21,31 @@
@SuppressWarnings("checkstyle:MagicNumber")
public final class Binary {
+ private static final int MAX_STRING_PACKET_SIZE = 20;
+
private Binary() {
// not instantiable
}
- public static String toString(byte[] data, int offset, int length) {
+ public static String buildPacketString(byte[] data, int offset, int len) {
+ int limit = Math.min(MAX_STRING_PACKET_SIZE, len);
StringBuilder builder = new StringBuilder();
- for (int i = 0; i < length; ++i) {
- byte b = data[offset + i];
- if (i % 16 == 0) {
- builder.append('\n');
- } else if (i % 8 == 0) {
- builder.append(' ');
+ builder.append('[').append(len).append(" bytes] ");
+ for (int i = 0; i < limit; ++i) {
+ if (i != 0) {
+ String sep = i % 4 == 0 ? " " : " ";
+ builder.append(sep);
}
- ++i;
- builder.append(String.format("%02X ", b & 0xff));
+ builder.append(String.format("%02X", data[offset + i] & 0xff));
+ }
+ if (limit < len) {
+ builder.append(" ... +").append(len - limit).append(" bytes");
}
return builder.toString();
}
- public static String toString(byte[] data) {
- return toString(data, 0, data.length);
- }
-
- public static String toString(ByteBuffer buffer) {
- return toString(buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.remaining());
+ public static String buildPacketString(ByteBuffer buffer) {
+ return buildPacketString(buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.remaining());
}
public static ByteBuffer copy(ByteBuffer buffer) {
diff --git a/relay-java/src/main/java/com/genymobile/gnirehtet/relay/IPv4Packet.java b/relay-java/src/main/java/com/genymobile/gnirehtet/relay/IPv4Packet.java
index ae0316e2..85ef2b1e 100644
--- a/relay-java/src/main/java/com/genymobile/gnirehtet/relay/IPv4Packet.java
+++ b/relay-java/src/main/java/com/genymobile/gnirehtet/relay/IPv4Packet.java
@@ -33,6 +33,10 @@ public IPv4Packet(ByteBuffer raw) {
this.raw = raw;
raw.rewind();
+ if (Log.isVerboseEnabled()) {
+ Log.v(TAG, "IPv4Packet: " + Binary.buildPacketString(raw));
+ }
+
ipv4Header = new IPv4Header(raw.duplicate());
if (!ipv4Header.isSupported()) {
Log.d(TAG, "Unsupported IPv4 headers");
diff --git a/relay-java/src/main/java/com/genymobile/gnirehtet/relay/Relay.java b/relay-java/src/main/java/com/genymobile/gnirehtet/relay/Relay.java
index 5d452c6a..d84b06f4 100644
--- a/relay-java/src/main/java/com/genymobile/gnirehtet/relay/Relay.java
+++ b/relay-java/src/main/java/com/genymobile/gnirehtet/relay/Relay.java
@@ -25,15 +25,10 @@ public class Relay {
private static final String TAG = Relay.class.getSimpleName();
- private static final int DEFAULT_PORT = 31416;
private static final int CLEANING_INTERVAL = 60 * 1000;
private final int port;
- public Relay() {
- this(DEFAULT_PORT);
- }
-
public Relay(int port) {
this.port = port;
}
@@ -53,11 +48,9 @@ public void run() throws IOException {
Set selectedKeys = selector.selectedKeys();
long now = System.currentTimeMillis();
- if (now >= nextCleaningDeadline) {
+ if (now >= nextCleaningDeadline || selectedKeys.isEmpty()) {
tunnelServer.cleanUp();
nextCleaningDeadline = now + CLEANING_INTERVAL;
- } else if (selectedKeys.isEmpty()) {
- throw new AssertionError("selector.select() returned without any event, an invalid SelectionKey was probably been registered");
}
for (SelectionKey selectedKey : selectedKeys) {
diff --git a/relay-java/src/main/java/com/genymobile/gnirehtet/relay/Router.java b/relay-java/src/main/java/com/genymobile/gnirehtet/relay/Router.java
index ef65738a..5ad6e1e7 100644
--- a/relay-java/src/main/java/com/genymobile/gnirehtet/relay/Router.java
+++ b/relay-java/src/main/java/com/genymobile/gnirehtet/relay/Router.java
@@ -40,7 +40,7 @@ public void sendToNetwork(IPv4Packet packet) {
if (!packet.isValid()) {
Log.w(TAG, "Dropping invalid packet");
if (Log.isVerboseEnabled()) {
- Log.v(TAG, Binary.toString(packet.getRaw()));
+ Log.v(TAG, Binary.buildPacketString(packet.getRaw()));
}
return;
}
diff --git a/relay-java/src/main/java/com/genymobile/gnirehtet/relay/TCPConnection.java b/relay-java/src/main/java/com/genymobile/gnirehtet/relay/TCPConnection.java
index 3cc09b8f..731b668f 100644
--- a/relay-java/src/main/java/com/genymobile/gnirehtet/relay/TCPConnection.java
+++ b/relay-java/src/main/java/com/genymobile/gnirehtet/relay/TCPConnection.java
@@ -353,7 +353,7 @@ private void handleAck(IPv4Packet packet) {
}
if (Log.isVerboseEnabled()) {
- logv(TAG, Binary.toString(packet.getRaw()));
+ logv(TAG, Binary.buildPacketString(packet.getRaw()));
}
int payloadLength = packet.getPayloadLength();
@@ -405,7 +405,7 @@ private IPv4Packet createEmptyResponsePacket(int flags) {
IPv4Packet packet = networkToClient.packetizeEmptyPayload();
logd(TAG, "Forging empty response (flags=" + flags + ") " + numbers());
if (Log.isVerboseEnabled()) {
- logd(TAG, Binary.toString(packet.getRaw()));
+ logd(TAG, Binary.buildPacketString(packet.getRaw()));
}
if ((flags & TCPHeader.FLAG_ACK) != 0) {
logd(TAG, "Acking " + numbers());
@@ -478,7 +478,7 @@ private void updateAcknowledgementNumber(IPv4Packet packet) {
public void next() {
logd(TAG, "Packet (" + packetForClient.getPayloadLength() + " bytes) sent to client " + numbers());
if (Log.isVerboseEnabled()) {
- logv(TAG, Binary.toString(packetForClient.getRaw()));
+ logv(TAG, Binary.buildPacketString(packetForClient.getRaw()));
}
sequenceNumber += packetForClient.getPayloadLength();
packetForClient = null;
diff --git a/relay-java/src/main/java/com/genymobile/gnirehtet/relay/UDPConnection.java b/relay-java/src/main/java/com/genymobile/gnirehtet/relay/UDPConnection.java
index e0fa0d7d..6dd506cb 100644
--- a/relay-java/src/main/java/com/genymobile/gnirehtet/relay/UDPConnection.java
+++ b/relay-java/src/main/java/com/genymobile/gnirehtet/relay/UDPConnection.java
@@ -137,7 +137,7 @@ private void pushToClient(IPv4Packet packet) {
}
logd(TAG, "Packet (" + packet.getPayloadLength() + " bytes) sent to client");
if (Log.isVerboseEnabled()) {
- logv(TAG, Binary.toString(packet.getRaw()));
+ logv(TAG, Binary.buildPacketString(packet.getRaw()));
}
}
diff --git a/relay-rust/Cargo.lock b/relay-rust/Cargo.lock
index 51c7aa09..c78116e1 100644
--- a/relay-rust/Cargo.lock
+++ b/relay-rust/Cargo.lock
@@ -1,48 +1,56 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "autocfg"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[[package]]
name = "bitflags"
-version = "1.0.4"
+version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
-version = "1.2.6"
+version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
-name = "cc"
-version = "1.0.23"
+name = "c2-chacha"
+version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
[[package]]
-name = "cfg-if"
-version = "0.1.5"
+name = "cc"
+version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
-name = "chrono"
-version = "0.4.6"
+name = "cfg-if"
+version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
-]
[[package]]
-name = "cloudabi"
-version = "0.0.3"
+name = "chrono"
+version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ctrlc"
-version = "3.1.1"
+version = "3.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -50,7 +58,7 @@ name = "fuchsia-zircon"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -59,26 +67,35 @@ name = "fuchsia-zircon-sys"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
+[[package]]
+name = "getrandom"
+version = "0.1.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "gnirehtet"
-version = "2.3.0"
+version = "2.5.0"
dependencies = [
- "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "ctrlc 3.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "iovec"
-version = "0.1.2"
+version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -90,39 +107,33 @@ dependencies = [
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
-[[package]]
-name = "lazycell"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
[[package]]
name = "libc"
-version = "0.2.43"
+version = "0.2.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "log"
-version = "0.4.4"
+version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "mio"
-version = "0.6.15"
+version = "0.6.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
- "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -142,71 +153,100 @@ name = "net2"
version = "0.2.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nix"
-version = "0.11.0"
+version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "cc 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)",
- "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-integer"
-version = "0.1.39"
+version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-traits"
-version = "0.2.5"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rand"
-version = "0.5.5"
+version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
-name = "rand_core"
+name = "rand_chacha"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_hc"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
[[package]]
name = "redox_syscall"
-version = "0.1.40"
+version = "0.1.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "slab"
-version = "0.4.1"
+version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "time"
-version = "0.1.40"
+version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -214,6 +254,11 @@ name = "void"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
+[[package]]
+name = "wasi"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[[package]]
name = "winapi"
version = "0.2.8"
@@ -221,7 +266,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
-version = "0.3.5"
+version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -253,34 +298,39 @@ dependencies = [
]
[metadata]
-"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
-"checksum byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90492c5858dd7d2e78691cfb89f90d273a2800fc11d98f60786e5d87e2f83781"
-"checksum cc 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)" = "c37f0efaa4b9b001fa6f02d4b644dee4af97d3414df07c51e3e4f015f3a3e131"
-"checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3"
-"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878"
-"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
-"checksum ctrlc 3.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "630391922b1b893692c6334369ff528dcc3a9d8061ccf4c803aa8f83cb13db5e"
+"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
+"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
+"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
+"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb"
+"checksum cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)" = "aa87058dce70a3ff5621797f1506cb837edd02ac4c0ae642b4542dce802908b8"
+"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
+"checksum chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e8493056968583b0193c1bb04d6f7684586f3726992d6c573261941a895dbd68"
+"checksum ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7dfd2d8b4c82121dfdff120f818e09fc4380b0b7e17a742081a89b94853e87f"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
-"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
+"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407"
+"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
-"checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef"
-"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d"
-"checksum log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cba860f648db8e6f269df990180c2217f333472b4a6e901e97446858487971e2"
-"checksum mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)" = "4fcfcb32d63961fb6f367bfd5d21e4600b92cd310f71f9dca25acae196eb1560"
+"checksum libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8"
+"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
+"checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23"
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
-"checksum nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d37e713a259ff641624b6cb20e3b12b2952313ba36b6823c0f16e6cfd9e5de17"
-"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
-"checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe"
-"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
-"checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2"
-"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
-"checksum slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d"
-"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
+"checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce"
+"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
+"checksum num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "443c53b3c3531dfcbfa499d8893944db78474ad7a1d87fa2d94d1a2231693ac6"
+"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
+"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412"
+"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853"
+"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
+"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
+"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
+"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
+"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
+"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
-"checksum winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "773ef9dcc5f24b7d850d0ff101e542ff24c3b090a9768e03ff889fdef41f00fd"
+"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
diff --git a/relay-rust/Cargo.toml b/relay-rust/Cargo.toml
index 55302894..13a22a85 100644
--- a/relay-rust/Cargo.toml
+++ b/relay-rust/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "gnirehtet"
-version = "2.3.0"
+version = "2.5.0"
authors = ["Romain Vimont "]
edition = "2018"
@@ -13,8 +13,8 @@ mio = "0.6" # for async I/O
slab = "0.4" # helper for mio Tokens
log = "0.4" # for logs
chrono = "0.4" # for formatting timestamp in logs
-byteorder = "1.2" # for reading/writing binary
-rand = "0.5" # for random TCP sequence number
+byteorder = "1.3" # for reading/writing binary
+rand = "0.7" # for random TCP sequence number
ctrlc = { version = "3.0", features = ["termination"] } # for handling Ctrl+C
[profile.release]
diff --git a/relay-rust/src/adb_monitor.rs b/relay-rust/src/adb_monitor.rs
index d09ad97e..102f79f2 100644
--- a/relay-rust/src/adb_monitor.rs
+++ b/relay-rust/src/adb_monitor.rs
@@ -57,7 +57,7 @@ impl AdbMonitor {
}
}
- pub fn monitor(&mut self) -> io::Result<()> {
+ pub fn monitor(&mut self) {
loop {
if let Err(err) = self.track_devices() {
error!(target: TAG, "Failed to monitor adb devices: {}", err);
diff --git a/relay-rust/src/cli_args.rs b/relay-rust/src/cli_args.rs
index 6968af02..438427fb 100644
--- a/relay-rust/src/cli_args.rs
+++ b/relay-rust/src/cli_args.rs
@@ -18,11 +18,15 @@ pub const PARAM_NONE: u8 = 0;
pub const PARAM_SERIAL: u8 = 1;
pub const PARAM_DNS_SERVERS: u8 = 1 << 1;
pub const PARAM_ROUTES: u8 = 1 << 2;
+pub const PARAM_PORT: u8 = 1 << 3;
+
+pub const DEFAULT_PORT: u16 = 31416;
pub struct CommandLineArguments {
serial: Option,
dns_servers: Option,
routes: Option,
+ port: u16,
}
impl CommandLineArguments {
@@ -31,6 +35,7 @@ impl CommandLineArguments {
let mut serial = None;
let mut dns_servers = None;
let mut routes = None;
+ let mut port = 0;
let mut iter = args.into_iter();
while let Some(arg) = iter.next() {
@@ -53,29 +58,49 @@ impl CommandLineArguments {
} else {
return Err(String::from("Missing -r parameter"));
}
+ } else if (accepted_parameters & PARAM_PORT) != 0 && "-p" == arg {
+ if port != 0 {
+ return Err(String::from("Port already set"));
+ }
+ if let Some(value) = iter.next() {
+ port = value.into().parse().unwrap();
+ if port == 0 {
+ return Err(String::from("Invalid port: 0"));
+ }
+ } else {
+ return Err(String::from("Missing -p parameter"));
+ }
} else if (accepted_parameters & PARAM_SERIAL) != 0 && serial.is_none() {
serial = Some(arg);
} else {
return Err(format!("Unexpected argument: \"{}\"", arg));
}
}
+ if port == 0 {
+ port = DEFAULT_PORT;
+ }
Ok(Self {
serial,
dns_servers,
routes,
+ port,
})
}
pub fn serial(&self) -> Option<&str> {
- self.serial.as_ref().map(String::as_str)
+ self.serial.as_deref()
}
pub fn dns_servers(&self) -> Option<&str> {
- self.dns_servers.as_ref().map(String::as_str)
+ self.dns_servers.as_deref()
}
pub fn routes(&self) -> Option<&str> {
- self.routes.as_ref().map(String::as_str)
+ self.routes.as_deref()
+ }
+
+ pub fn port(&self) -> u16 {
+ self.port
}
}
diff --git a/relay-rust/src/execution_error.rs b/relay-rust/src/execution_error.rs
index 90be6545..39b5610b 100644
--- a/relay-rust/src/execution_error.rs
+++ b/relay-rust/src/execution_error.rs
@@ -107,15 +107,7 @@ impl fmt::Display for ProcessStatusError {
}
}
-impl error::Error for ProcessStatusError {
- fn description(&self) -> &str {
- "Execution terminated with failure"
- }
-
- fn cause(&self) -> Option<&error::Error> {
- None
- }
-}
+impl error::Error for ProcessStatusError {}
impl ProcessIoError {
pub fn new(cmd: Cmd, error: io::Error) -> Self {
@@ -130,11 +122,7 @@ impl fmt::Display for ProcessIoError {
}
impl error::Error for ProcessIoError {
- fn description(&self) -> &str {
- "Execution I/O failed"
- }
-
- fn cause(&self) -> Option<&error::Error> {
+ fn source(&self) -> Option<&(dyn error::Error + 'static)> {
Some(&self.error)
}
}
@@ -150,15 +138,7 @@ impl fmt::Display for CommandExecutionError {
}
impl error::Error for CommandExecutionError {
- fn description(&self) -> &str {
- match *self {
- CommandExecutionError::ProcessIo(ref err) => err.description(),
- CommandExecutionError::ProcessStatus(ref err) => err.description(),
- CommandExecutionError::Io(ref err) => err.description(),
- }
- }
-
- fn cause(&self) -> Option<&error::Error> {
+ fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match *self {
CommandExecutionError::ProcessIo(ref err) => Some(err),
CommandExecutionError::ProcessStatus(ref err) => Some(err),
diff --git a/relay-rust/src/lib.rs b/relay-rust/src/lib.rs
index 5c149108..e50ca4e7 100644
--- a/relay-rust/src/lib.rs
+++ b/relay-rust/src/lib.rs
@@ -20,7 +20,6 @@ pub use crate::relay::byte_buffer;
use crate::relay::Relay;
use std::io;
-pub fn relay() -> io::Result<()> {
- const PORT: u16 = 31416;
- Relay::new(PORT).run()
+pub fn relay(port: u16) -> io::Result<()> {
+ Relay::new(port).run()
}
diff --git a/relay-rust/src/main.rs b/relay-rust/src/main.rs
index 44e8eb36..cb80e9c8 100644
--- a/relay-rust/src/main.rs
+++ b/relay-rust/src/main.rs
@@ -34,9 +34,27 @@ use std::thread;
use std::time::Duration;
const TAG: &str = "Main";
-const REQUIRED_APK_VERSION_CODE: &str = "6";
+const REQUIRED_APK_VERSION_CODE: &str = "8";
-const COMMANDS: &[&Command] = &[
+#[inline]
+fn get_adb_path() -> String {
+ if let Some(env_adb) = std::env::var_os("ADB") {
+ env_adb.into_string().expect("invalid ADB value")
+ } else {
+ "adb".to_string()
+ }
+}
+
+#[inline]
+fn get_apk_path() -> String {
+ if let Some(env_adb) = std::env::var_os("GNIREHTET_APK") {
+ env_adb.into_string().expect("invalid GNIREHTET_APK value")
+ } else {
+ "gnirehtet.apk".to_string()
+ }
+}
+
+const COMMANDS: &[&dyn Command] = &[
&InstallCommand,
&UninstallCommand,
&ReinstallCommand,
@@ -133,7 +151,10 @@ impl Command for RunCommand {
}
fn accepted_parameters(&self) -> u8 {
- cli_args::PARAM_SERIAL | cli_args::PARAM_DNS_SERVERS | cli_args::PARAM_ROUTES
+ cli_args::PARAM_SERIAL
+ | cli_args::PARAM_DNS_SERVERS
+ | cli_args::PARAM_ROUTES
+ | cli_args::PARAM_PORT
}
fn description(&self) -> &'static str {
@@ -145,7 +166,12 @@ impl Command for RunCommand {
}
fn execute(&self, args: &CommandLineArguments) -> Result<(), CommandExecutionError> {
- cmd_run(args.serial(), args.dns_servers(), args.routes())
+ cmd_run(
+ args.serial(),
+ args.dns_servers(),
+ args.routes(),
+ args.port(),
+ )
}
}
@@ -155,7 +181,7 @@ impl Command for AutorunCommand {
}
fn accepted_parameters(&self) -> u8 {
- cli_args::PARAM_DNS_SERVERS | cli_args::PARAM_ROUTES
+ cli_args::PARAM_DNS_SERVERS | cli_args::PARAM_ROUTES | cli_args::PARAM_PORT
}
fn description(&self) -> &'static str {
@@ -165,7 +191,7 @@ impl Command for AutorunCommand {
}
fn execute(&self, args: &CommandLineArguments) -> Result<(), CommandExecutionError> {
- cmd_autorun(args.dns_servers(), args.routes())
+ cmd_autorun(args.dns_servers(), args.routes(), args.port())
}
}
@@ -175,7 +201,10 @@ impl Command for StartCommand {
}
fn accepted_parameters(&self) -> u8 {
- cli_args::PARAM_SERIAL | cli_args::PARAM_DNS_SERVERS | cli_args::PARAM_ROUTES
+ cli_args::PARAM_SERIAL
+ | cli_args::PARAM_DNS_SERVERS
+ | cli_args::PARAM_ROUTES
+ | cli_args::PARAM_PORT
}
fn description(&self) -> &'static str {
@@ -186,13 +215,20 @@ impl Command for StartCommand {
DNS server(s). Otherwise, use 8.8.8.8 (Google public DNS).\n\
If -r is given, then only reverse tether the specified routes.\n\
Otherwise, use 0.0.0.0/0 (redirect the whole traffic).\n\
+ If -p is given, then make the relay server listen on the specified\n\
+ port. Otherwise, use port 31416.\n\
If the client is already started, then do nothing, and ignore\n\
the other parameters.\n\
10.0.2.2 is mapped to the host 'localhost'."
}
fn execute(&self, args: &CommandLineArguments) -> Result<(), CommandExecutionError> {
- cmd_start(args.serial(), args.dns_servers(), args.routes())
+ cmd_start(
+ args.serial(),
+ args.dns_servers(),
+ args.routes(),
+ args.port(),
+ )
}
}
@@ -202,7 +238,7 @@ impl Command for AutostartCommand {
}
fn accepted_parameters(&self) -> u8 {
- cli_args::PARAM_DNS_SERVERS | cli_args::PARAM_ROUTES
+ cli_args::PARAM_DNS_SERVERS | cli_args::PARAM_ROUTES | cli_args::PARAM_PORT
}
fn description(&self) -> &'static str {
@@ -213,7 +249,7 @@ impl Command for AutostartCommand {
}
fn execute(&self, args: &CommandLineArguments) -> Result<(), CommandExecutionError> {
- cmd_autostart(args.dns_servers(), args.routes())
+ cmd_autostart(args.dns_servers(), args.routes(), args.port())
}
}
@@ -243,7 +279,10 @@ impl Command for RestartCommand {
}
fn accepted_parameters(&self) -> u8 {
- cli_args::PARAM_SERIAL | cli_args::PARAM_DNS_SERVERS | cli_args::PARAM_ROUTES
+ cli_args::PARAM_SERIAL
+ | cli_args::PARAM_DNS_SERVERS
+ | cli_args::PARAM_ROUTES
+ | cli_args::PARAM_PORT
}
fn description(&self) -> &'static str {
@@ -252,7 +291,12 @@ impl Command for RestartCommand {
fn execute(&self, args: &CommandLineArguments) -> Result<(), CommandExecutionError> {
cmd_stop(args.serial())?;
- cmd_start(args.serial(), args.dns_servers(), args.routes())?;
+ cmd_start(
+ args.serial(),
+ args.dns_servers(),
+ args.routes(),
+ args.port(),
+ )?;
Ok(())
}
}
@@ -263,7 +307,7 @@ impl Command for TunnelCommand {
}
fn accepted_parameters(&self) -> u8 {
- cli_args::PARAM_SERIAL
+ cli_args::PARAM_SERIAL | cli_args::PARAM_PORT
}
fn description(&self) -> &'static str {
@@ -274,7 +318,7 @@ impl Command for TunnelCommand {
}
fn execute(&self, args: &CommandLineArguments) -> Result<(), CommandExecutionError> {
- cmd_tunnel(args.serial())
+ cmd_tunnel(args.serial(), args.port())
}
}
@@ -284,22 +328,22 @@ impl Command for RelayCommand {
}
fn accepted_parameters(&self) -> u8 {
- cli_args::PARAM_NONE
+ cli_args::PARAM_NONE | cli_args::PARAM_PORT
}
fn description(&self) -> &'static str {
"Start the relay server in the current terminal."
}
- fn execute(&self, _: &CommandLineArguments) -> Result<(), CommandExecutionError> {
- cmd_relay()?;
+ fn execute(&self, args: &CommandLineArguments) -> Result<(), CommandExecutionError> {
+ cmd_relay(args.port())?;
Ok(())
}
}
fn cmd_install(serial: Option<&str>) -> Result<(), CommandExecutionError> {
info!(target: TAG, "Installing gnirehtet client...");
- exec_adb(serial, vec!["install", "-r", "gnirehtet.apk"])
+ exec_adb(serial, vec!["install".into(), "-r".into(), get_apk_path()])
}
fn cmd_uninstall(serial: Option<&str>) -> Result<(), CommandExecutionError> {
@@ -317,9 +361,10 @@ fn cmd_run(
serial: Option<&str>,
dns_servers: Option<&str>,
routes: Option<&str>,
+ port: u16,
) -> Result<(), CommandExecutionError> {
// start in parallel so that the relay server is ready when the client connects
- async_start(serial, dns_servers, routes);
+ async_start(serial, dns_servers, routes, port);
let ctrlc_serial = serial.map(String::from);
ctrlc::set_handler(move || {
@@ -334,12 +379,13 @@ fn cmd_run(
})
.expect("Error setting Ctrl-C handler");
- cmd_relay()
+ cmd_relay(port)
}
fn cmd_autorun(
dns_servers: Option<&str>,
routes: Option<&str>,
+ port: u16,
) -> Result<(), CommandExecutionError> {
{
let autostart_dns_servers = dns_servers.map(String::from);
@@ -347,19 +393,20 @@ fn cmd_autorun(
thread::spawn(move || {
let dns_servers = autostart_dns_servers.as_ref().map(String::as_ref);
let routes = autostart_routes.as_ref().map(String::as_ref);
- if let Err(err) = cmd_autostart(dns_servers, routes) {
+ if let Err(err) = cmd_autostart(dns_servers, routes, port) {
error!(target: TAG, "Cannot auto start clients: {}", err);
}
});
}
- cmd_relay()
+ cmd_relay(port)
}
fn cmd_start(
serial: Option<&str>,
dns_servers: Option<&str>,
routes: Option<&str>,
+ port: u16,
) -> Result<(), CommandExecutionError> {
if must_install_client(serial)? {
cmd_install(serial)?;
@@ -369,16 +416,16 @@ fn cmd_start(
}
info!(target: TAG, "Starting client...");
- cmd_tunnel(serial)?;
+ cmd_tunnel(serial, port)?;
let mut adb_args = vec![
"shell",
"am",
- "broadcast",
+ "start",
"-a",
"com.genymobile.gnirehtet.START",
"-n",
- "com.genymobile.gnirehtet/.GnirehtetControlReceiver",
+ "com.genymobile.gnirehtet/.GnirehtetActivity",
];
if let Some(dns_servers) = dns_servers {
adb_args.append(&mut vec!["--esa", "dnsServers", dns_servers]);
@@ -392,15 +439,16 @@ fn cmd_start(
fn cmd_autostart(
dns_servers: Option<&str>,
routes: Option<&str>,
+ port: u16,
) -> Result<(), CommandExecutionError> {
let start_dns_servers = dns_servers.map(String::from);
let start_routes = routes.map(String::from);
let mut adb_monitor = AdbMonitor::new(Box::new(move |serial: &str| {
let dns_servers = start_dns_servers.as_ref().map(String::as_ref);
let routes = start_routes.as_ref().map(String::as_ref);
- async_start(Some(serial), dns_servers, routes)
+ async_start(Some(serial), dns_servers, routes, port)
}));
- adb_monitor.monitor()?;
+ adb_monitor.monitor();
Ok(())
}
@@ -411,29 +459,33 @@ fn cmd_stop(serial: Option<&str>) -> Result<(), CommandExecutionError> {
vec![
"shell",
"am",
- "broadcast",
+ "start",
"-a",
"com.genymobile.gnirehtet.STOP",
"-n",
- "com.genymobile.gnirehtet/.GnirehtetControlReceiver",
+ "com.genymobile.gnirehtet/.GnirehtetActivity",
],
)
}
-fn cmd_tunnel(serial: Option<&str>) -> Result<(), CommandExecutionError> {
+fn cmd_tunnel(serial: Option<&str>, port: u16) -> Result<(), CommandExecutionError> {
exec_adb(
serial,
- vec!["reverse", "localabstract:gnirehtet", "tcp:31416"],
+ vec![
+ "reverse",
+ "localabstract:gnirehtet",
+ format!("tcp:{}", port).as_str(),
+ ],
)
}
-fn cmd_relay() -> Result<(), CommandExecutionError> {
- info!(target: TAG, "Starting relay server...");
- relaylib::relay()?;
+fn cmd_relay(port: u16) -> Result<(), CommandExecutionError> {
+ info!(target: TAG, "Starting relay server on port {}...", port);
+ relaylib::relay(port)?;
Ok(())
}
-fn async_start(serial: Option<&str>, dns_servers: Option<&str>, routes: Option<&str>) {
+fn async_start(serial: Option<&str>, dns_servers: Option<&str>, routes: Option<&str>, port: u16) {
let start_serial = serial.map(String::from);
let start_dns_servers = dns_servers.map(String::from);
let start_routes = routes.map(String::from);
@@ -441,7 +493,7 @@ fn async_start(serial: Option<&str>, dns_servers: Option<&str>, routes: Option<&
let serial = start_serial.as_ref().map(String::as_ref);
let dns_servers = start_dns_servers.as_ref().map(String::as_ref);
let routes = start_routes.as_ref().map(String::as_ref);
- if let Err(err) = cmd_start(serial, dns_servers, routes) {
+ if let Err(err) = cmd_start(serial, dns_servers, routes, port) {
error!(target: TAG, "Cannot start client: {}", err);
}
});
@@ -464,18 +516,19 @@ fn exec_adb>(
args: Vec,
) -> Result<(), CommandExecutionError> {
let adb_args = create_adb_args(serial, args);
- debug!(target: TAG, "Execute: adb {:?}", adb_args);
- match process::Command::new("adb").args(&adb_args[..]).status() {
+ let adb = get_adb_path();
+ debug!(target: TAG, "Execute: {:?} {:?}", adb, adb_args);
+ match process::Command::new(&adb).args(&adb_args[..]).status() {
Ok(exit_status) => {
if exit_status.success() {
Ok(())
} else {
- let cmd = Cmd::new("adb", adb_args);
+ let cmd = Cmd::new(adb, adb_args);
Err(ProcessStatusError::new(cmd, exit_status).into())
}
}
Err(err) => {
- let cmd = Cmd::new("adb", adb_args);
+ let cmd = Cmd::new(adb, adb_args);
Err(ProcessIoError::new(cmd, err).into())
}
}
@@ -487,8 +540,9 @@ fn must_install_client(serial: Option<&str>) -> Result {
if output.status.success() {
// the "regex" crate makes the binary far bigger, so just parse the versionCode
@@ -509,12 +563,12 @@ fn must_install_client(serial: Option<&str>) -> Result {
- let cmd = Cmd::new("adb", args);
+ let cmd = Cmd::new(adb, args);
Err(ProcessIoError::new(cmd, err).into())
}
}
@@ -545,6 +599,9 @@ fn append_command_usage(msg: &mut String, command: &dyn Command) {
if (accepted_parameters & cli_args::PARAM_DNS_SERVERS) != 0 {
msg.push_str(" [-d DNS[,DNS2,...]]");
}
+ if (accepted_parameters & cli_args::PARAM_PORT) != 0 {
+ msg.push_str(" [-p PORT]");
+ }
if (accepted_parameters & cli_args::PARAM_ROUTES) != 0 {
msg.push_str(" [-r ROUTE[,ROUTE2,...]]");
}
diff --git a/relay-rust/src/relay/binary.rs b/relay-rust/src/relay/binary.rs
index 15e58b9c..47a58294 100644
--- a/relay-rust/src/relay/binary.rs
+++ b/relay-rust/src/relay/binary.rs
@@ -15,23 +15,29 @@
*/
use byteorder::{BigEndian, ByteOrder};
+use std::cmp::min;
use std::fmt::Write;
+const MAX_STRING_PACKET_SIZE: usize = 20;
+
pub fn to_byte_array(value: u32) -> [u8; 4] {
let mut raw = [0u8; 4];
BigEndian::write_u32(&mut raw, value);
raw
}
-pub fn to_string(data: &[u8]) -> String {
+pub fn build_packet_string(data: &[u8]) -> String {
let mut s = String::new();
- for (i, &byte) in data.iter().enumerate() {
- if i % 16 == 0 {
- writeln!(&mut s).unwrap();
- } else if i % 8 == 0 {
- write!(&mut s, " ").unwrap();
+ let limit = min(MAX_STRING_PACKET_SIZE, data.len());
+ for (i, &byte) in data.iter().take(limit).enumerate() {
+ if i != 0 {
+ let sep = if (i % 4) == 0 { " " } else { " " };
+ write!(&mut s, "{}", sep).unwrap();
}
- write!(&mut s, "{:02X} ", byte).unwrap();
+ write!(&mut s, "{:02X}", byte).unwrap();
+ }
+ if limit < data.len() {
+ write!(&mut s, " ... +{} bytes", data.len() - limit).unwrap();
}
s
}
diff --git a/relay-rust/src/relay/byte_buffer.rs b/relay-rust/src/relay/byte_buffer.rs
index 01cc476e..50a1c8c2 100644
--- a/relay-rust/src/relay/byte_buffer.rs
+++ b/relay-rust/src/relay/byte_buffer.rs
@@ -30,7 +30,7 @@ impl ByteBuffer {
}
}
- pub fn read_from(&mut self, source: &mut R) -> io::Result<(bool)> {
+ pub fn read_from(&mut self, source: &mut R) -> io::Result {
let target_slice = &mut self.buf[self.head..];
let r = source.read(target_slice)?;
self.head += r;
diff --git a/relay-rust/src/relay/client.rs b/relay-rust/src/relay/client.rs
index 7861dc8b..b98a85f6 100644
--- a/relay-rust/src/relay/client.rs
+++ b/relay-rust/src/relay/client.rs
@@ -287,7 +287,7 @@ impl Client {
self.channel().update_interests(selector);
}
- fn read(&mut self) -> io::Result<(bool)> {
+ fn read(&mut self) -> io::Result {
self.client_to_network.read_from(&mut self.stream)
}
diff --git a/relay-rust/src/relay/ipv4_packet_buffer.rs b/relay-rust/src/relay/ipv4_packet_buffer.rs
index 0d526dc5..a0a42f7d 100644
--- a/relay-rust/src/relay/ipv4_packet_buffer.rs
+++ b/relay-rust/src/relay/ipv4_packet_buffer.rs
@@ -14,9 +14,12 @@
* limitations under the License.
*/
+use super::binary;
use super::byte_buffer::ByteBuffer;
use super::ipv4_header;
use super::ipv4_packet::{Ipv4Packet, MAX_PACKET_LENGTH};
+
+use log::*;
use std::io;
pub struct Ipv4PacketBuffer {
@@ -30,12 +33,13 @@ impl Ipv4PacketBuffer {
}
}
- pub fn read_from(&mut self, source: &mut R) -> io::Result<(bool)> {
+ pub fn read_from(&mut self, source: &mut R) -> io::Result {
self.buf.read_from(source)
}
fn available_packet_length(&self) -> Option {
let data = self.buf.peek();
+ trace!("Parse packet: {}", binary::build_packet_string(data));
if let Some((version, length)) = ipv4_header::peek_version_length(data) {
assert!(version == 4, "Not an Ipv4 packet, version={}", version);
if length as usize <= data.len() {
diff --git a/relay-rust/src/relay/router.rs b/relay-rust/src/relay/router.rs
index fb366d02..88a8d9e6 100644
--- a/relay-rust/src/relay/router.rs
+++ b/relay-rust/src/relay/router.rs
@@ -83,7 +83,11 @@ impl Router {
} else {
warn!(target: TAG, "Dropping invalid packet");
if log_enabled!(target: TAG, Level::Trace) {
- trace!(target: TAG, "{}", binary::to_string(ipv4_packet.raw()));
+ trace!(
+ target: TAG,
+ "{}",
+ binary::build_packet_string(ipv4_packet.raw())
+ );
}
}
}
diff --git a/relay-rust/src/relay/tcp_connection.rs b/relay-rust/src/relay/tcp_connection.rs
index 91af24a6..4935f306 100644
--- a/relay-rust/src/relay/tcp_connection.rs
+++ b/relay-rust/src/relay/tcp_connection.rs
@@ -682,7 +682,7 @@ impl TcpConnection {
target: TAG,
self.id,
"{}",
- binary::to_string(ipv4_packet.raw())
+ binary::build_packet_string(ipv4_packet.raw())
);
}
@@ -720,7 +720,12 @@ impl TcpConnection {
}
let ipv4_packet = packetizer.packetize_empty_payload();
if log_enabled!(target: TAG, Level::Trace) {
- cx_trace!(target: TAG, id, "{}", binary::to_string(ipv4_packet.raw()));
+ cx_trace!(
+ target: TAG,
+ id,
+ "{}",
+ binary::build_packet_string(ipv4_packet.raw())
+ );
}
ipv4_packet
}
@@ -785,7 +790,16 @@ impl Connection for TcpConnection {
fn close(&mut self, selector: &mut Selector) {
cx_info!(target: TAG, self.id, "Close");
self.closed = true;
- selector.deregister(&self.stream, self.token).unwrap();
+ if let Err(err) = selector.deregister(&self.stream, self.token) {
+ // do not panic, this can happen in mio
+ // see
+ cx_warn!(
+ target: TAG,
+ self.id,
+ "Fail to deregister TCP stream: {:?}",
+ err
+ );
+ }
// socket will be closed by RAII
}
diff --git a/relay-rust/src/relay/tunnel_server.rs b/relay-rust/src/relay/tunnel_server.rs
index 2976bdf6..7ae2f3bd 100644
--- a/relay-rust/src/relay/tunnel_server.rs
+++ b/relay-rust/src/relay/tunnel_server.rs
@@ -15,7 +15,7 @@
*/
use log::*;
-use mio::tcp::TcpListener;
+use mio::net::TcpListener;
use mio::{Event, PollOpt, Ready};
use std::cell::RefCell;
use std::io;
diff --git a/relay-rust/src/relay/udp_connection.rs b/relay-rust/src/relay/udp_connection.rs
index f07d6ee7..936d578b 100644
--- a/relay-rust/src/relay/udp_connection.rs
+++ b/relay-rust/src/relay/udp_connection.rs
@@ -206,7 +206,7 @@ impl UdpConnection {
target: TAG,
self.id,
"{}",
- binary::to_string(ipv4_packet.raw())
+ binary::build_packet_string(ipv4_packet.raw())
);
}
}
@@ -271,7 +271,16 @@ impl Connection for UdpConnection {
fn close(&mut self, selector: &mut Selector) {
cx_info!(target: TAG, self.id, "Close");
self.closed = true;
- selector.deregister(&self.socket, self.token).unwrap();
+ if let Err(err) = selector.deregister(&self.socket, self.token) {
+ // do not panic, this can happen in mio
+ // see
+ cx_warn!(
+ target: TAG,
+ self.id,
+ "Fail to deregister UDP stream: {:?}",
+ err
+ );
+ }
// socket will be closed by RAII
}
diff --git a/setup/AdbWinApi.dll b/setup/AdbWinApi.dll
new file mode 100644
index 00000000..7abe26cf
Binary files /dev/null and b/setup/AdbWinApi.dll differ
diff --git a/setup/AdbWinUsbApi.dll b/setup/AdbWinUsbApi.dll
new file mode 100644
index 00000000..e7a6de12
Binary files /dev/null and b/setup/AdbWinUsbApi.dll differ
diff --git a/setup/adb.exe b/setup/adb.exe
new file mode 100644
index 00000000..623fa466
Binary files /dev/null and b/setup/adb.exe differ
diff --git a/setup/fastboot.exe b/setup/fastboot.exe
new file mode 100644
index 00000000..2a5d7683
Binary files /dev/null and b/setup/fastboot.exe differ
diff --git a/setup/gnirehtet-autorun.lnk b/setup/gnirehtet-autorun.lnk
new file mode 100644
index 00000000..57a549c7
Binary files /dev/null and b/setup/gnirehtet-autorun.lnk differ
diff --git a/setup/gnirehtet-run.cmd b/setup/gnirehtet-run.cmd
new file mode 100644
index 00000000..ffefea65
--- /dev/null
+++ b/setup/gnirehtet-run.cmd
@@ -0,0 +1,2 @@
+@gnirehtet.exe run
+@pause
diff --git a/setup/gnirehtet.apk b/setup/gnirehtet.apk
new file mode 100644
index 00000000..7327ab74
Binary files /dev/null and b/setup/gnirehtet.apk differ
diff --git a/setup/gnirehtet.exe b/setup/gnirehtet.exe
new file mode 100644
index 00000000..fc31676b
Binary files /dev/null and b/setup/gnirehtet.exe differ
diff --git a/setup/libwinpthread-1.dll b/setup/libwinpthread-1.dll
new file mode 100644
index 00000000..94e343a6
Binary files /dev/null and b/setup/libwinpthread-1.dll differ
diff --git a/setup/remote-install_app.cmd b/setup/remote-install_app.cmd
new file mode 100644
index 00000000..549452c5
--- /dev/null
+++ b/setup/remote-install_app.cmd
@@ -0,0 +1,6 @@
+@adb start-server
+@adb push -p app.apk /data/local/tmp
+@adb shell pm install /data/local/tmp/app.apk
+@adb shell rm /data/local/tmp/app.apk
+@adb kill-server
+@pause