Skip to content

Commit cbc8a66

Browse files
committed
Init.
0 parents  commit cbc8a66

19 files changed

+1116
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.gradle
2+
app/.externalNativeBuild
3+
app/build

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "app/src/main/jni/hev-socks5-tunnel"]
2+
path = app/src/main/jni/hev-socks5-tunnel
3+
url = https://github.com/heiher/hev-socks5-tunnel

License

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2023 hev
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of
4+
this software and associated documentation files (the "Software"), to deal in
5+
the Software without restriction, including without limitation the rights to
6+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7+
of the Software, and to permit persons to whom the Software is furnished to do
8+
so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
SOFTWARE.

README.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# SocksTun
2+
3+
A simple and lightweight VPN over socks5 proxy for Android. It is based on a high-performance and low-overhead [tun2socks](https://github.com/heiher/hev-socks5-tunnel).
4+
5+
## Features
6+
7+
* Redirect TCP connections.
8+
* Redirect UDP packets. (Fullcone NAT, UDP over TCP, works with [hev-socks5-server](https://github.com/heiher/hev-socks5-server) only)
9+
* Simple username/password authentication.
10+
* Specifying DNS addresses.
11+
* IPv4/IPv6 dual stack.
12+
* Global/per-App modes.
13+
14+
## How to Build
15+
16+
```bash
17+
git clone --recursive https://github.com/heiher/sockstun
18+
cd sockstun
19+
gradle assembleDebug
20+
```
21+
22+
## Server side
23+
24+
```bash
25+
git clone --recursive https://github.com/heiher/hev-socks5-server
26+
cd hev-socks5-server
27+
make
28+
29+
hev-socks5-server conf.yml
30+
```
31+
32+
```yaml
33+
main:
34+
workers: 4
35+
port: 1080
36+
listen-address: '::'
37+
38+
misc:
39+
limit-nofile: 65535
40+
```
41+
42+
## Dependencies
43+
44+
* HevSocks5Tunnel - https://github.com/heiher/hev-socks5-tunnel
45+
46+
## Contributors
47+
48+
* **hev** - https://hev.cc
49+
50+
## License
51+
52+
MIT

app/build.gradle

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
apply plugin: 'com.android.application'
2+
3+
android {
4+
compileSdkVersion 24
5+
6+
defaultConfig {
7+
applicationId "hev.sockstun"
8+
minSdkVersion 24
9+
targetSdkVersion 24
10+
versionCode 1
11+
versionName "1.0"
12+
setProperty("archivesBaseName", "$applicationId-$versionName")
13+
ndk {
14+
abiFilters "armeabi-v7a", "arm64-v8a"
15+
}
16+
}
17+
18+
signingConfigs {
19+
release {
20+
}
21+
}
22+
23+
buildTypes {
24+
release {
25+
minifyEnabled false
26+
signingConfig signingConfigs.release
27+
}
28+
}
29+
30+
def propsFile = rootProject.file('gradle.properties')
31+
def configName = 'release'
32+
33+
if (propsFile.exists() && android.signingConfigs.hasProperty(configName)) {
34+
def props = new Properties()
35+
props.load(new FileInputStream(propsFile))
36+
if (props!=null && props.containsKey('storeFile')) {
37+
android.signingConfigs[configName].storeFile = rootProject.file(props['storeFile'])
38+
android.signingConfigs[configName].storePassword = props['storePassword']
39+
android.signingConfigs[configName].keyAlias = props['keyAlias']
40+
android.signingConfigs[configName].keyPassword = props['keyPassword']
41+
}
42+
}
43+
44+
externalNativeBuild {
45+
ndkBuild {
46+
path "src/main/jni/Android.mk"
47+
}
48+
}
49+
50+
lintOptions {
51+
checkReleaseBuilds false
52+
// Or, if you prefer, you can continue to check for errors in release builds,
53+
// but continue the build even when errors are found:
54+
abortOnError false
55+
}
56+
}
57+

app/src/main/AndroidManifest.xml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
package="hev.sockstun">
4+
<application android:label="@string/app_name" android:theme="@android:style/Theme.Holo">
5+
<service android:name=".TProxyService" android:process=":native"
6+
android:permission="android.permission.BIND_VPN_SERVICE">
7+
<intent-filter>
8+
<action android:name="android.net.VpnService"/>
9+
</intent-filter>
10+
</service>
11+
<receiver android:enabled="true" android:name=".ServiceReceiver">
12+
<intent-filter>
13+
<action android:name="android.intent.action.BOOT_COMPLETED"/>
14+
</intent-filter>
15+
</receiver>
16+
<activity android:name=".MainActivity" android:label="@string/app_name"
17+
android:excludeFromRecents="true">
18+
<intent-filter>
19+
<action android:name="android.intent.action.MAIN"/>
20+
<category android:name="android.intent.category.LAUNCHER"/>
21+
</intent-filter>
22+
</activity>
23+
<activity android:name=".AppListActivity" android:label="@string/app_name"/>
24+
</application>
25+
<uses-permission android:name="android.permission.INTERNET"/>
26+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
27+
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
28+
</manifest>
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/*
2+
============================================================================
3+
Name : AppListActivity.java
4+
Author : hev <r@hev.cc>
5+
Copyright : Copyright (c) 2023 xyz
6+
Description : App List Activity
7+
============================================================================
8+
*/
9+
10+
package hev.sockstun;
11+
12+
import java.util.Set;
13+
import java.util.List;
14+
import java.util.Arrays;
15+
import java.util.HashSet;
16+
import java.util.Iterator;
17+
import java.util.Comparator;
18+
import java.util.Collections;
19+
import android.Manifest;
20+
import android.os.Bundle;
21+
import android.app.ListActivity;
22+
import android.view.View;
23+
import android.view.ViewGroup;
24+
import android.view.LayoutInflater;
25+
import android.widget.ArrayAdapter;
26+
import android.widget.CheckBox;
27+
import android.widget.ImageView;
28+
import android.widget.ListView;
29+
import android.widget.TextView;
30+
import android.content.Context;
31+
import android.content.pm.PackageManager;
32+
import android.content.pm.PackageInfo;
33+
import android.content.pm.ApplicationInfo;
34+
35+
public class AppListActivity extends ListActivity {
36+
private Preferences prefs;
37+
private boolean isChanged = false;
38+
39+
private class Package {
40+
public PackageInfo info;
41+
public boolean selected;
42+
public String label;
43+
44+
public Package(PackageInfo info, boolean selected, String label) {
45+
this.info = info;
46+
this.selected = selected;
47+
this.label = label;
48+
}
49+
}
50+
51+
private class AppArrayAdapter extends ArrayAdapter<Package> {
52+
public AppArrayAdapter(Context context) {
53+
super(context, R.layout.appitem);
54+
}
55+
56+
@Override
57+
public View getView(int position, View convertView, ViewGroup parent) {
58+
LayoutInflater inflater = (LayoutInflater) getContext()
59+
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
60+
View rowView = inflater.inflate(R.layout.appitem, parent, false);
61+
ImageView imageView = (ImageView) rowView.findViewById(R.id.icon);
62+
TextView textView = (TextView) rowView.findViewById(R.id.name);
63+
CheckBox checkBox = (CheckBox) rowView.findViewById(R.id.checked);
64+
65+
Package pkg = getItem(position);
66+
PackageManager pm = getContext().getPackageManager();
67+
ApplicationInfo appinfo = pkg.info.applicationInfo;
68+
imageView.setImageDrawable(appinfo.loadIcon(pm));
69+
textView.setText(appinfo.loadLabel(pm).toString());
70+
checkBox.setChecked(pkg.selected);
71+
72+
return rowView;
73+
}
74+
}
75+
76+
@Override
77+
public void onCreate(Bundle savedInstanceState) {
78+
super.onCreate(savedInstanceState);
79+
80+
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
81+
82+
prefs = new Preferences(this);
83+
Set<String> apps = prefs.getApps();
84+
PackageManager pm = getPackageManager();
85+
AppArrayAdapter adapter = new AppArrayAdapter(this);
86+
87+
for (PackageInfo info : pm.getInstalledPackages(PackageManager.GET_PERMISSIONS)) {
88+
if (info.packageName.equals(getPackageName()))
89+
continue;
90+
if (info.requestedPermissions == null)
91+
continue;
92+
if (!Arrays.asList(info.requestedPermissions).contains(Manifest.permission.INTERNET))
93+
continue;
94+
boolean selected = apps.contains(info.packageName);
95+
String label = info.applicationInfo.loadLabel(pm).toString();
96+
Package pkg = new Package(info, selected, label);
97+
adapter.add(pkg);
98+
}
99+
100+
adapter.sort(new Comparator<Package>() {
101+
public int compare(Package a, Package b) {
102+
if (a.selected != b.selected)
103+
return a.selected ? -1 : 1;
104+
return a.label.compareTo(b.label);
105+
}
106+
});
107+
108+
setListAdapter(adapter);
109+
}
110+
111+
@Override
112+
protected void onDestroy() {
113+
if (isChanged) {
114+
AppArrayAdapter adapter = (AppArrayAdapter) getListView().getAdapter();
115+
Set<String> apps = new HashSet<String>();
116+
117+
for (int i = 0; i < adapter.getCount(); i++) {
118+
Package pkg = adapter.getItem(i);
119+
if (pkg.selected)
120+
apps.add(pkg.info.packageName);
121+
}
122+
123+
prefs.setApps(apps);
124+
}
125+
126+
super.onDestroy();
127+
}
128+
129+
@Override
130+
protected void onListItemClick(ListView l, View v, int position, long id) {
131+
AppArrayAdapter adapter = (AppArrayAdapter) l.getAdapter();
132+
adapter.getItem(position).selected = !adapter.getItem(position).selected;
133+
CheckBox checkbox = (CheckBox) v.findViewById(R.id.checked);
134+
checkbox.setChecked(adapter.getItem(position).selected);
135+
isChanged = true;
136+
}
137+
}

0 commit comments

Comments
 (0)