refactor clash bridge

This commit is contained in:
Kr328 committed 2020-06-10 21:24:38 +08:00
1 parent 2759f59029
commit 432fa115e2
6 files changed
+69 -53

No files matched your search

+7 -7
View File
@@ -66,10 +66,10 @@ jobject Master::Context::newTraffic(long upload, long download) {
return env->NewObject(master->cTraffic, master->cTrafficConstructor, upload, download);
}
jobject Master::Context::newGeneral(std::string const &mode, int http, int socks, int redirect,
jobject Master::Context::newGeneral(char const *mode, int http, int socks, int redirect,
int mixed) {
return env->NewObject(master->cGeneral, master->cGeneralConstructor,
env->NewStringUTF(mode.c_str()), http, socks, redirect, mixed);
env->NewStringUTF(mode), http, socks, redirect, mixed);
}
jobject Master::Context::newCompletableFuture() {
@@ -141,7 +141,7 @@ jobjectArray Master::Context::createProxyArray(int size, jobject elements[]) {
return result;
}
jobject Master::Context::createProxy(std::string const &name, proxy_type_t type, long delay) {
jobject Master::Context::createProxy(char const *name, proxy_type_t type, long delay) {
jstring ts = nullptr;
switch (type) {
@@ -191,11 +191,11 @@ jobject Master::Context::createProxy(std::string const &name, proxy_type_t type,
ts = master->sUnknown;
}
return env->NewObject(master->cProxy, master->cProxyConstructor, env->NewStringUTF(name.c_str()), ts, delay);
return env->NewObject(master->cProxy, master->cProxyConstructor, env->NewStringUTF(name), ts, delay);
}
jobject Master::Context::createProxyGroup(std::string const &name, proxy_type_t type,
std::string const &current, jobjectArray proxies) {
jobject Master::Context::createProxyGroup(char const *name, proxy_type_t type,
char const *current, jobjectArray proxies) {
jstring ts = nullptr;
switch (type) {
@@ -221,7 +221,7 @@ jobject Master::Context::createProxyGroup(std::string const &name, proxy_type_t
ts = master->sUnknown;
}
return env->NewObject(master->cProxyGroup, master->cProxyGroupConstructor, env->NewStringUTF(name.c_str()), ts, env->NewStringUTF(current.c_str()), proxies);
return env->NewObject(master->cProxyGroup, master->cProxyGroupConstructor, env->NewStringUTF(name), ts, env->NewStringUTF(current), proxies);
}
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *unused) {
+3 -3
View File
@@ -70,7 +70,7 @@ public:
public:
jthrowable newClashException(std::string const &message);
jobject newTraffic(long upload, long download);
jobject newGeneral(std::string const &mode, int http, int socks, int redirect, int mixed);
jobject newGeneral(char const *mode, int http, int socks, int redirect, int mixed);
jobject newCompletableFuture();
public:
@@ -87,8 +87,8 @@ public:
void tunCallbackStop(jobject callback);
public:
jobject createProxy(std::string const &name, proxy_type_t type, long delay);
jobject createProxyGroup(std::string const &name, proxy_type_t type, std::string const &current, jobjectArray proxies);
jobject createProxy(char const *name, proxy_type_t type, long delay);
jobject createProxyGroup(char const *name, proxy_type_t type, char const *current, jobjectArray proxies);
jobjectArray createProxyArray(int size, jobject elements[]);
jobjectArray createProxyGroupArray(int size, jobject elements[]);
const_buffer_t createConstBufferFromByteArray(jbyteArray array);
+7 -7
View File
@@ -71,30 +71,29 @@ Java_com_github_kr328_clash_core_bridge_Bridge_queryProxyGroups(JNIEnv *env, jcl
auto *jgroups = new jobject[list->size];
for (int group_index = 0 ; group_index < list->size ; group_index++ ) {
std::string now;
char const * now = "";
proxy_group_t *group = list->groups[group_index];
auto *jproxies = new jobject[group->proxies_size];
const char *group_name = &list->string_pool[group->base.name_index];
for ( int proxy_index = 0 ; proxy_index < group->proxies_size ; proxy_index++ ) {
proxy_t *proxy = &group->proxies[proxy_index];
const char *name = &list->string_pool[proxy->name_index];
jproxies[proxy_index] = context->createProxy(proxy->name, proxy->proxy_type, proxy->delay);
jproxies[proxy_index] = context->createProxy(name, proxy->proxy_type, proxy->delay);
if ( proxy_index == group->now )
now = proxy->name;
free(proxy->name);
now = name;
}
jgroups[group_index] = context->createProxyGroup(
group->base.name,
group_name,
group->base.proxy_type,
now,
context->createProxyArray(group->proxies_size, jproxies));
delete[] jproxies;
free(group->base.name);
free(group);
}
@@ -102,6 +101,7 @@ Java_com_github_kr328_clash_core_bridge_Bridge_queryProxyGroups(JNIEnv *env, jcl
delete[] jgroups;
free(list->string_pool);
free(list);
return result;
+6 -3
View File
@@ -9,7 +9,6 @@ import "C"
import (
"runtime"
"sync"
"sync/atomic"
"unsafe"
)
@@ -21,9 +20,10 @@ type ccallContext struct {
argument unsafe.Pointer
}
var ccallQueue chan *ccallContext
var ccallQueue = make(chan *ccallContext)
var ccallMap sync.Map
var currentIndex uint64
var indexLock sync.Mutex
func init() {
C.initialize_ccall(C.int(runtime.NumCPU()))
@@ -45,9 +45,12 @@ func callCcall(call nativeCcall, argument unsafe.Pointer) {
func nextCcall(ccall *nativeCcall, argument *unsafe.Pointer, index *uint64) {
ctx := <- ccallQueue
*index = atomic.AddUint64(&currentIndex, 1)
indexLock.Lock()
currentIndex++
*index = currentIndex
*ccall = ctx.call
*argument = ctx.argument
indexLock.Unlock()
ccallMap.Store(*index, ctx)
}
+44 -32
View File
@@ -6,38 +6,13 @@ import (
"github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/log"
"github.com/Dreamacro/clash/tunnel"
"unsafe"
)
/*
#cgo CFLAGS: -Werror
#include "buffer.h"
#include "proxies.h"
#include <malloc.h>
static proxy_group_list_t *new_proxy_group_list_t(int size) {
proxy_group_list_t *result = (proxy_group_list_t *) malloc(sizeof(proxy_group_list_t) + size * sizeof(proxy_group_t*));
result->size = size;
return result;
}
static proxy_group_t *new_proxy_group_t(int proxies_size) {
proxy_group_t *result = (proxy_group_t *) malloc(sizeof(proxy_group_t) + proxies_size * sizeof(proxy_t));
result->proxies_size = proxies_size;
return result;
}
static proxy_t *proxy_group_get_proxy(proxy_group_t *group, int index) {
return &group->proxies[index];
}
static void proxy_group_list_set(proxy_group_list_t *list, int index, proxy_group_t *group) {
list->groups[index] = group;
}
*/
import "C"
@@ -87,6 +62,7 @@ func setSelector(group C.const_string_t, selected C.const_string_t) C.int {
//export queryProxyGroups
func queryProxyGroups() *C.proxy_group_list_t {
stringPool := make([]byte, 0, 4096)
proxies := tunnel.Proxies()
groups := make([]outboundgroup.ProxyGroup, 0, len(proxies))
@@ -104,7 +80,7 @@ func queryProxyGroups() *C.proxy_group_list_t {
groups = append(groups, adapter)
}
result := C.new_proxy_group_list_t(C.int(len(groups)))
result := allocCProxyGroupList(len(groups))
groupIndex := 0
for _, group := range groups {
ps := make([]constant.Proxy, 0)
@@ -112,20 +88,26 @@ func queryProxyGroups() *C.proxy_group_list_t {
ps = append(ps, provider.Proxies()...)
}
g := C.new_proxy_group_t(C.int(len(proxies)))
g := allocCProxyGroup(len(proxies))
g.base.name = C.CString(group.Name())
g.base.name_index = C.long(len(stringPool))
g.base.proxy_type = typeToProxyTypeC(group.Type())
g.base.delay = 0
stringPool = append(stringPool, group.Name()...)
stringPool = append(stringPool, 0)
proxyIndex := 0
for _, proxy := range proxies {
p := C.proxy_group_get_proxy(g, C.int(proxyIndex))
p := indexCProxyGroupElement(g, proxyIndex)
p.name = C.CString(proxy.Name())
p.name_index = C.long(len(stringPool))
p.proxy_type = typeToProxyTypeC(proxy.Type())
p.delay = C.long(proxy.LastDelay())
stringPool = append(stringPool, proxy.Name()...)
stringPool = append(stringPool, 0)
if proxy.Name() == group.Now() {
g.now = C.int(proxyIndex)
}
@@ -133,14 +115,18 @@ func queryProxyGroups() *C.proxy_group_list_t {
proxyIndex++
}
C.proxy_group_list_set(result, C.int(groupIndex), g)
setCProxyGroupListElement(result, groupIndex, g)
groupIndex++
}
result.string_pool = (*C.char)(C.CBytes(stringPool))
return result
}
func typeToProxyTypeC(t constant.AdapterType) C.proxy_type_t {
switch t {
case constant.Direct:
@@ -175,4 +161,30 @@ func typeToProxyTypeC(t constant.AdapterType) C.proxy_type_t {
default:
return C.Unknown
}
}
func allocCProxyGroup(proxiesSize int) *C.proxy_group_t {
return (*C.proxy_group_t)(C.malloc(C.sizeof_proxy_group_t + C.sizeof_proxy_t * C.size_t(proxiesSize)))
}
func allocCProxyGroupList(groupSize int) *C.proxy_group_list_t {
return (*C.proxy_group_list_t)(C.malloc(C.sizeof_proxy_group_list_t + C.sizeof_long * C.size_t(groupSize)))
}
//noinspection GoVetUnsafePointer
func setCProxyGroupListElement(list *C.proxy_group_list_t, index int, element *C.proxy_group_t) {
address := uintptr(unsafe.Pointer(list))
offset := address + uintptr(C.sizeof_proxy_group_list_t) + uintptr(index) * uintptr(C.sizeof_long)
*(**C.proxy_group_t)(unsafe.Pointer(offset)) = element
}
//noinspection GoVetUnsafePointer
func indexCProxyGroupElement(group *C.proxy_group_t, index int) *C.proxy_t {
address := uintptr(unsafe.Pointer(group))
offset := address + uintptr(C.sizeof_proxy_group_list_t) + uintptr(index) * uintptr(C.sizeof_proxy_t)
return (*C.proxy_t)(unsafe.Pointer(offset))
}
+2 -1
View File
@@ -9,7 +9,7 @@ typedef enum proxy_type_t {
} proxy_type_t;
typedef struct proxy_t {
char *name;
long name_index;
proxy_type_t proxy_type;
long delay;
} proxy_t;
@@ -23,6 +23,7 @@ typedef struct proxy_group_t {
typedef struct proxy_group_list_t {
int size;
char *string_pool;
proxy_group_t *groups[];
} proxy_group_list_t;