refactor clash bridge
This commit is contained in:
6 files changed
+69
-53
No files matched your search
@@ -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 ¤t, 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) {
|
||||
|
||||
@@ -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 ¤t, 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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(¤tIndex, 1)
|
||||
indexLock.Lock()
|
||||
currentIndex++
|
||||
*index = currentIndex
|
||||
*ccall = ctx.call
|
||||
*argument = ctx.argument
|
||||
indexLock.Unlock()
|
||||
|
||||
ccallMap.Store(*index, ctx)
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in new issue
Block a user