Commit e57d5993 by 王一诺

init

parents
Showing with 5026 additions and 0 deletions
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
# Default ignored files
/shelf/
/workspace.xml
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="17" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetSelector">
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
</SelectionState>
</selectionStates>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/app/src/main/cpp/include/VpsMgr.h" charset="ISO-8859-1" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveExternalAnnotations" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectMigrations">
<option name="MigrateToGradleLocalJavaHome">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
\ No newline at end of file
/build
\ No newline at end of file
plugins {
alias(libs.plugins.android.application)
}
android {
namespace 'com.coolook.vps'
compileSdk 34
defaultConfig {
applicationId "com.coolook.vps"
minSdk 27
targetSdk 34
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
// externalNativeBuild {
// cmake {
// cppFlags '-std=c++11'
// }
// }
}
// externalNativeBuild {
// cmake {
// path file('src/main/cpp/CMakeLists.txt')
// version '3.22.1'
// }
// }
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation libs.appcompat
implementation libs.material
implementation libs.activity
implementation libs.constraintlayout
testImplementation libs.junit
androidTestImplementation libs.ext.junit
androidTestImplementation libs.espresso.core
}
\ No newline at end of file
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
\ No newline at end of file
package com.coolook.vps;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.coolook.vps", appContext.getPackageName());
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Vps"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
\ No newline at end of file
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html.
# For more examples on how to use CMake, see https://github.com/android/ndk-samples.
# Sets the minimum CMake version required for this project.
cmake_minimum_required(VERSION 3.22.1)
# Declares the project name. The project name can be accessed via ${ PROJECT_NAME},
# Since this is the top level CMakeLists.txt, the project name is also accessible
# with ${CMAKE_PROJECT_NAME} (both CMake variables are in-sync within the top level
# build script scope).
project("vps_sdk")
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
#
# In this top level CMakeLists.txt, ${CMAKE_PROJECT_NAME} is used to define
# the target library name; in the sub-module's CMakeLists.txt, ${PROJECT_NAME}
# is preferred for the same purpose.
#
# In order to load a library into your app from Java/Kotlin, you must call
# System.loadLibrary() and pass the name of the library defined here;
# for GameActivity/NativeActivity derived applications, the same library name must be
# used in the AndroidManifest.xml file.
# 设置 include 目录
include_directories(include)
file(GLOB SOURCES "src/*.cpp")
add_library(${CMAKE_PROJECT_NAME} SHARED
# List C/C++ source files with relative paths to this CMakeLists.txt.
${SOURCES}
)
# Specifies libraries CMake should link to your target library. You
# can link libraries from various origins, such as libraries defined in this
# build script, prebuilt third-party libraries, or Android system libraries.
target_link_libraries(${CMAKE_PROJECT_NAME}
# List libraries link to the target library
android
log)
\ No newline at end of file
#pragma once
#include "zxlist.h"
#include "semx.h"
typedef struct
{
struct list_head head;
semx_t *sem;
int id_next;
}channel_mgr_t;
typedef struct
{
struct list_head node;
int id;
int fd;
}channel_node_t;
extern channel_mgr_t g_channel_mgr;
int channel_mgr_init(channel_mgr_t *mgr);
int channel_mgr_release(channel_mgr_t *mgr);
int channel_mgr_list_clear(channel_mgr_t *mgr);
int channel_mgr_add_node(channel_mgr_t *mgr, channel_node_t *node);
int channel_mgr_del_node(channel_mgr_t *mgr, int id);
channel_node_t* channel_mgr_get_node(channel_mgr_t *mgr, int id);
channel_node_t* channel_mgr_get_node_and_del_from_list(channel_mgr_t *mgr, int id);
// id: 加入到channel_mgr的id, 用于删除结点
int channel_mgr_send_data_to_sdk(channel_mgr_t *mgr, int fd, unsigned char *data, int datalen, int *id);
int channel_mgr_send_data_to_server(channel_mgr_t *mgr, int id, unsigned char *data, int datalen);
#pragma once
#include "zxlist.h"
#include "zxstruct.h"
#include "zxstring.h"
typedef struct _data_queue_node_t data_queue_node_t;
typedef struct _data_queue_t data_queue_t;
struct _data_queue_node_t
{
struct list_head node;
unsigned short len;
unsigned char type;
unsigned char refer;
unsigned char *data;
};
data_queue_node_t *data_queue_node_create(unsigned char type, unsigned char refer, unsigned char * data, unsigned int len);
void data_queue_node_release(data_queue_node_t *node);
data_queue_t *data_queue_create();
int data_queue_add_data(data_queue_t *data_queue, unsigned char type, unsigned char refer, unsigned char *data, unsigned int len);
void data_queue_add_data(data_queue_t *data_queue, data_queue_node_t *node);
void data_queue_del_data(data_queue_t * data_queue, unsigned char refer, unsigned char type);
data_queue_node_t *data_queue_get_first(data_queue_t *data_queue);
zxuint64 data_queue_total_size(data_queue_t *data_queue);
int data_queue_is_empty(data_queue_t *data_queue); // 0: empty, not 0: not empty
void data_queue_release(data_queue_t *data_queue);
#pragma once
#include "zxlist.h"
#include "zxselect.h"
#include "zxstring.h"
#include "ChannelMgr.h"
#include "flowStatistics.h"
#include "DataQueue.h"
#define VPS_SO_VERSION_CODE 19
#define VPS_SO_VERSION_NAME "1.2.7"
#define VPS_KEY ("vps_test_key")
#define VPS_ENCODE_ENABLE 1
#define VPS_ENCODE_DISABLE 0
typedef struct _vps_mgr_t
{
struct list_head workNodeHeader; //vps work node
int fd; //Ӿ
int waitHeartResponse;
int encode;
select_t *st;
select_node_t *node;
zx_string *zxsRecvData;
zx_string *zxsSendData;
zx_string *zxsKey;
zx_string *zxsIMSI;
unsigned int offsetRecvData;
unsigned int offsetSendData;
int heartbeatTimeout;
unsigned int heartbeatLastRecv;
channel_mgr_t *channel_mgr;
flow_statistics_t *flow_statistics;
zxuint64 time_last_print_flow;
data_queue_t *data_queue;
unsigned int flow_limit;
unsigned int flow_limit_earlier;
unsigned int flow_cache;
zxuint64 time_last_flow_limit_calc;
}vps_mgr_t;
void vps_mgr_set_config(int timeout_connect);
void vps_mgr_set_exit_timestamp(long long exit_timestamp);
void vps_mgr_set_bind_addr(const char *ip);
int start(const char *szHost, int nPort, const char *szIMSI);
int close();
int vps_mgr_set_channel_response(int id, unsigned char *data, int datalen);
#pragma once
#include "zxlist.h"
#include "zxstring.h"
#include "node.h"
typedef struct _work_node_t work_node_t;
struct _work_node_t
{
// node_t
//node_t node;
struct list_head node;
vps_mgr_t *mgr;
int refer;
p_func_call_back_get_flow_limit get_flow_limit;
p_func_call_back_transfer_data transfer_data;
p_func_call_back_delete_data delete_data;
p_func_call_back_remove_node remove_node;
p_func_node_release release;
p_func_node_recv_package recv_package;
// _work_node_t
int fd;
int closeRequest;
//int closeResponse;
zx_string *zxsTransferData;
zx_string *zxsResponseData;
unsigned int offsetTransferData;
unsigned int offsetResponseData;
select_node_t *snode;
int sync_resp; // 1: response send back; 0: no response
unsigned int totalResponseSize;
int sendBytys;
int recvBytes;
flow_statistics_t *flow_statistics;
zxint64 lastModeWithRead;
int read2k;
};
node_t *work_node_create(int refer, vps_mgr_t *mgr, p_func_call_back_get_flow_limit get_flow_limit,
p_func_call_back_transfer_data transfer_data, p_func_call_back_delete_data delete_data, p_func_call_back_remove_node remove_node);
void work_node_set_config(int timeout_connect, int timeout_total);
\ No newline at end of file
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_z_s_S */
#ifndef _Included_com_z_s_S
#define _Included_com_z_s_S
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_z_s_S
* Method: setVtimeout
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_com_z_s_S_setVtimeout
(JNIEnv *, jclass, jint);
/*
* Class: com_z_s_S
* Method: setStimeout
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_z_s_S_setStimeout
(JNIEnv *, jclass, jint, jint);
/*
* Class: com_z_s_S
* Method: start
* Signature: (Ljava/lang/String;ILjava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_com_z_s_S_start
(JNIEnv *, jclass, jstring, jint, jstring);
/*
* Class: com_z_s_S
* Method: close
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_z_s_S_close
(JNIEnv *, jclass);
/*
* Class: com_z_s_S
* Method: getVcode
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_z_s_S_getVcode
(JNIEnv *, jclass);
/*
* Class: com_z_s_S
* Method: getVname
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_z_s_S_getVname
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
typedef struct {
unsigned char *buf;
int buf_size;
int buf_used;
}liuguan_buffer_t;
void liuguan_buffer_init(liuguan_buffer_t *liuguan_buffer);
void liuguan_buffer_clean(liuguan_buffer_t *liuguan_buffer);
int http_get(const char *url, liuguan_buffer_t *p_liuguan_buffer);
int http_get(const char *bind_addr, const char *url, liuguan_buffer_t *p_liuguan_buffer);
int http_post(const char *url, const unsigned char *post_data, unsigned int data_len, liuguan_buffer_t *p_liuguan_buffer);
int http_post(const char *bind_addr, const char *url, const unsigned char *post_data, unsigned int data_len, liuguan_buffer_t *p_liuguan_buffer);
\ No newline at end of file
#pragma once
#include "zxlist.h"
#include "zxstring.h"
#include "node.h"
typedef struct _fifo_node_t fifo_node_t;
struct _fifo_node_t
{
// node_t
struct list_head node;
vps_mgr_t *mgr;
int refer;
p_func_call_back_get_flow_limit get_flow_limit;
p_func_call_back_transfer_data transfer_data;
p_func_call_back_delete_data delete_data;
p_func_call_back_remove_node remove_node;
p_func_node_release release;
p_func_node_recv_package recv_package;
// _fifo_node_t
int fd[2];
int id;
int closeRequest;
int closeResponse;
zx_string *zxsTransferData;
zx_string *zxsResponseData;
select_node_t *snode;
};
node_t *fifo_node_create(int refer, vps_mgr_t *mgr, p_func_call_back_get_flow_limit get_flow_limit,
p_func_call_back_transfer_data transfer_data, p_func_call_back_delete_data delete_data, p_func_call_back_remove_node remove_node);
#pragma once
#include "zxlist.h"
#include "zxstruct.h"
typedef struct _flow_statistics_t flow_statistics_t;
typedef struct _flow_second_t flow_second_t;
struct _flow_second_t
{
struct list_head node; // 链表
zxuint64 time; //时间
zxuint64 bytes; //该单位时间内总计的流量
};
struct _flow_statistics_t
{
struct list_head flow_read;
struct list_head flow_write;
zxuint64 total_read_bytes;
zxuint64 total_write_bytes;
int statistical_interval; //统计区间, 单位秒
};
flow_second_t *create_flow_second(zxuint64 time, zxuint64 byte_count);
flow_statistics_t *create_flow_statistics();
flow_statistics_t *create_flow_statistics(int statistical_interval);
void flow_statistics_release(flow_statistics_t *fs);
void add_read_bytes(flow_statistics_t *flow_statistics, zxuint64 time, unsigned int byte_count);
void add_write_bytes(flow_statistics_t *flow_statistics, zxuint64 time, unsigned int byte_count);
zxuint64 get_read_bytes_with_statistical_interval(flow_statistics_t *flow_statistics, zxuint64 time);
zxuint64 get_write_bytes_with_statistical_interval(flow_statistics_t *flow_statistics, zxuint64 time);
\ No newline at end of file
#pragma once
#include "VpsMgr.h"
typedef struct _node_t node_t;
typedef unsigned int(*p_func_call_back_get_flow_limit)(vps_mgr_t *mgr);
typedef int(*p_func_call_back_transfer_data)(vps_mgr_t *mgr, int type, int refer, unsigned char *data, int datalen, int is_cmd);
typedef int(*p_func_call_back_delete_data)(vps_mgr_t *mgr, int type, int refer);
typedef int(*p_func_call_back_remove_node)(vps_mgr_t *mgr, node_t *node);
typedef int(*p_func_node_release)(struct _node_t *node);
typedef int(*p_func_node_recv_package)(struct _node_t *node, int type, int refer, unsigned char *data, int datalen);
struct _node_t
{
struct list_head node;
int refer;
vps_mgr_t *mgr;
p_func_call_back_get_flow_limit get_flow_limit;
p_func_call_back_transfer_data transfer_data;
p_func_call_back_delete_data delete_data;
p_func_call_back_remove_node remove_node;
p_func_node_release release;
p_func_node_recv_package recv_package;
};
\ No newline at end of file
#ifndef __SEMX_H__
#define __SEMX_H__
typedef struct _semx_t semx_t;
semx_t * semaphore_create();
int semaphore_wait(semx_t *sem);
int semaphore_post(semx_t *sem);
int semphore_close(semx_t *sem);
#endif // __SEMX_H__
#ifndef __SYSTEM_H__
#define __SYSTEM_H__
// 内存泄露检查 配置方法 _CrtDumpMemoryLeaks(); 使用
#ifdef WIN32
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#endif // WIN32
// sleep
#endif // __SYSTEM_H__
\ No newline at end of file
#ifndef __ZX_LIST_BASE__
#define __ZX_LIST_BASE__
//计算member在type中的位置
#define offset_of(type, member) (size_t)(&((type*)0)->member)
//根据member的地址获取type的起始地址
#define container_of(ptr, type, member) ((type *)((char *)ptr - offset_of(type, member)))
//链表结构
struct list_head
{
struct list_head *prev;
struct list_head *next;
};
static inline void init_list_head(struct list_head *list)
{
list->prev = list;
list->next = list;
}
static inline void __list_add(struct list_head *_new,
struct list_head *prev, struct list_head *next)
{
prev->next = _new;
_new->prev = prev;
_new->next = next;
next->prev = _new;
}
//从头部添加
static inline void list_add(struct list_head *_new , struct list_head *head)
{
__list_add(_new, head, head->next);
}
//从尾部添加
static inline void list_add_tail(struct list_head *_new, struct list_head *head)
{
__list_add(_new, head->prev, head);
}
static inline void __list_del(struct list_head *prev, struct list_head *next)
{
prev->next = next;
next->prev = prev;
}
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
}
static inline void list_move(struct list_head *list, struct list_head *head)
{
__list_del(list->prev, list->next);
list_add(list, head);
}
static inline void list_move_tail(struct list_head *list,
struct list_head *head)
{
__list_del(list->prev, list->next);
list_add_tail(list, head);
}
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
#define list_first_entry(ptr, type, member) \
list_entry((ptr)->next, type, member)
#define list_last_entry(ptr, type, member) \
list_entry((ptr)->prev, type, member)
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
#define list_is_empty(head) \
((head)->prev == head)
#endif //__ZX_LIST_BASE__
#ifndef __ZX_LOG_H__
#define __ZX_LOG_H__
#include <stdio.h>
#include <stdlib.h>
#include "system.h"
#ifdef ANDROID
#include <android/log.h>
#ifdef __cplusplus
extern "C" {
#endif
//#define YWT_DEBUG_MODE //disable it @release
#ifdef YWT_DEBUG_MODE
#define LOG_TAG "ZxVps"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
static void printBuf(unsigned char* buf, int len) {
char b[1024] = { 0 };
int i = 0;
for (i = 0; i < len; i++) {
sprintf(b + (i % 100) * 3, "%02X ", buf[i]);
if (((i + 1) % 100) == 0) {
LOGD("%s", b);
memset(b, 0, sizeof(b));
}
}
if ((i % 100) != 0) {
LOGD("%s", b);
}
LOGD("\n");
}
#else
#define LOGD(...)
#define LOGI(...)
#define LOGE(...)
#define LOGW(...)
#endif
#ifdef __cplusplus
}
#endif
#elif defined(linux)
#include <string.h>
#include <time.h>
#define LOGFORMAT(x, format, ...) { \
time_t now = time(NULL); \
struct tm *t = localtime(&now); \
char *buf = (char *)malloc(strlen(format) + 1024); \
sprintf(buf, "%02d/%02d/%02d %02d:%02d:%02d [%-5s] %s\n", (t->tm_year + 1900)%100, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, x, format); \
printf(buf, ##__VA_ARGS__); \
free(buf); \
fflush(stdout); \
}
#define LOGD(format, ...)
#define LOGI(format, ...) LOGFORMAT("INFO", format, ##__VA_ARGS__)
#define LOGE(format, ...) LOGFORMAT("WARN", format, ##__VA_ARGS__)
#define LOGW(format, ...) LOGFORMAT("ERROR", format, ##__VA_ARGS__)
#else // ANDROID
#include <string.h>
#include <time.h>
#define LOGFORMAT(x, format, ...) { \
struct tm t; \
time_t now = time(NULL); \
localtime_s(&t, &now); \
char *buf = (char *)malloc(strlen(format) + 1024); \
sprintf_s(buf, strlen(format) + 1024, "%02d/%02d/%02d %02d:%02d:%02d [%-5s] %s\n", (t.tm_year + 1900)%100, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, x, format); \
printf(buf, ##__VA_ARGS__); \
free(buf); \
}
#ifdef _DEBUG
#define LOGD(format, ...) LOGFORMAT("DEBUG", format, ##__VA_ARGS__)
#define LOGI(format, ...) LOGFORMAT("INFO", format, ##__VA_ARGS__)
#define LOGE(format, ...) LOGFORMAT("WARN", format, ##__VA_ARGS__)
#define LOGW(format, ...) LOGFORMAT("ERROR", format, ##__VA_ARGS__)
#else
#define LOGD(format, ...)
#define LOGI(format, ...) LOGFORMAT("INFO", format, ##__VA_ARGS__)
#define LOGE(format, ...) LOGFORMAT("WARN", format, ##__VA_ARGS__)
#define LOGW(format, ...) LOGFORMAT("ERROR", format, ##__VA_ARGS__)
#endif // _DEBUG
#endif // ANDROID
#endif //__ZX_LOG_H__
#ifndef __ZX_PIPE__
#define __ZX_PIPE__
//´´½¨pipe
int pipe_init();
int pipe_release();
int pipe_create(int * fd);
void pipe_close(int * fd);
int pipe_write(int fd, const unsigned char * data, int len);
int pipe_read(int fd, char *buf, int bufsize);
#endif //__ZX_PIPE__
#ifndef __ZXSELECT__
#define __ZXSELECT__
#include "zxlist.h"
#include <time.h>
//#include <sys/types.h>
#define SELECT_MODE_CONNECT 0x1
#define SELECT_MODE_READ 0x2
#define SELECT_MODE_WRITE 0x4
#define SELECT_MODE_ERROR 0x8
//#define SELECT_MODE_WAIT 0x10
typedef void (*p_func_call_back_connected)(void *param, int fd);
typedef void (*p_func_call_back_read)(void *param, int fd, unsigned char *buf, int bufsize);
typedef void (*p_func_call_back_write)(void *param, int fd);
typedef void (*p_func_call_back_timeout)(void *param, int fd);
typedef void (*p_func_call_back_del)(void *param, int fd);
typedef int(*p_func_call_back_get_mode)(void *param, int fd);
typedef void(*p_func_call_back_prepare)(void *param, int fd);
typedef struct _select_node_t
{
struct list_head node;
void *param;
p_func_call_back_connected connected;
p_func_call_back_read read;
p_func_call_back_write write;
p_func_call_back_timeout timeout;
p_func_call_back_del del;
p_func_call_back_get_mode get_mode;
p_func_call_back_prepare prepare;
int fd;
int selectMode;
time_t timeAdd;
long timeOut;
int delnode;
}select_node_t;
typedef struct _select_t select_t;
int select_init(select_t **st);
int select_release(select_t *st);
int select_fd_add(select_t *st, select_node_t *node);
select_node_t * select_create_node();
void select_node_release(select_node_t *node);
void select_thread(select_t *st, long long exit_timestamp);
void select_thread_exit(select_t *st);
#endif //__ZXSELECT__
#ifndef __ZX_SOCKET__
#define __ZX_SOCKET__
//´´½¨·Ç×èÈûsocket
int socket_create_nonblock(int * _fd);
void socket_close(int fd);
int socket_connect(int refer, int fd, const char * szHost, int port);
int socket_connect(int refer, int fd, const struct sockaddr_in * addr, int port);
int socket_read(int fd, char *buf, int bufsize);
int socket_write(int fd, char *buf, int bufsize);
void glob_bind_addr_set(const char *ip);
#endif //__ZX_SOCKET__
#ifndef __ZX_STRING__
#define __ZX_STRING__
#define STRING_ERROR -1
#define STRING_OK 0
#define STRING_NPOS 0xFFFFFFFF
typedef struct _zx_string zx_string;
zx_string* string_create();
zx_string* string_create_chars(const char *);
zx_string* string_create_size(unsigned int size = 0);
zx_string* string_create_bin(const unsigned char *, unsigned int);
zx_string* string_create_zxs(zx_string *);
void string_release(zx_string *);
int string_add_chars(zx_string *, const char *);
int string_add_uint(zx_string *, unsigned int);
int string_add_int(zx_string *, int);
int string_add_bin(zx_string *, const unsigned char *, unsigned int);
int string_add_zxs(zx_string *, zx_string *);
int string_clear(zx_string *);
char* string_detach(zx_string **);
char* string_get_data(zx_string *);
unsigned int string_get_len(zx_string *);
int string_tolower(zx_string *);
int string_toupper(zx_string *);
unsigned int string_find_chars(zx_string *, const char *, unsigned int pos = 0);
unsigned int string_find_char(zx_string *, const char, unsigned int pos = 0);
zx_string* string_substr_begin(zx_string *, unsigned int);
zx_string* string_substr_begin_cnt(zx_string *, unsigned int, unsigned int);
int string_swap(zx_string *, zx_string *);
int string_to_uint(zx_string *, unsigned int *n);
#endif //__ZX_STRING__
#ifndef __ZX_STRUCT__
#define __ZX_STRUCT__
#define RET_OK 0
#define RET_ERROR -1
#define TYPE_CHANNEL_TO_SDK_BEGIN 0x41
#define TYPE_CHANNEL_TO_SDK_ING 0x42
#define TYPE_CHANNEL_TO_SDK_END 0x43
#define TYPE_CHANNEL_TO_SERVER_BEGIN 0x44
#define TYPE_CHANNEL_TO_SERVER_ING 0x45
#define TYPE_CHANNEL_TO_SERVER_END 0x46
#define TYPE_ERROR 0x51
#define TYPE_OK 0x52
#define TYPE_CONNECT 0x53
#define TYPE_TRANS_DATA 0x54
#define TYPE_CONNECT_CLOSE 0x55
#define TYPE_ENCODE_ENABLE 0x56
#define TYPE_SET_NEW_KEY 0x57
#define TYPE_GET_IMSI 0x58
#define TYPE_GET_VERNAME 0x59
#define TYPE_GET_VERCODE 0x5A
#define TYPE_SET_VPS_TOTAL_IDLE 0x5B
#define TYPE_SET_HEARTBEAT_TIMEOUT 0x5C
#define TYPE_RESP_SIZE_SYNC 0x61 //未回传 response的字节数同步到服务,用于服务端统计
#define TYPE_REFER_DEL_SYNC 0x62
#define TYPE_OPT_NO_RESP 0xC0 //异步response
#define TYPE_ERROR_UNKNOW_TYPE 0xE1
#define TYPE_ERROR_IN_FIFO 0xE2
// 心跳字段
#define TYPE_HEART 0xFF
typedef long long zxint64;
typedef unsigned long long zxuint64;
extern zxuint64 g_time;
#endif //__ZX_STRUCT__
#include "../include/ChannelMgr.h"
#include "../include/zxstruct.h"
#include <stdlib.h>
#include "../include/zxlog.h"
#include "../include/zxpipe.h"
#include <unistd.h>
extern int callback_to_java_channel(int id, unsigned char *data, int datalen);
channel_mgr_t g_channel_mgr = { 0 };
zxuint64 g_time = 0;
int channel_mgr_init(channel_mgr_t * mgr)
{
init_list_head(&mgr->head);
mgr->id_next = 1;
mgr->sem = semaphore_create();
semaphore_post(mgr->sem);
return RET_OK;
}
int channel_mgr_release(channel_mgr_t * mgr)
{
int ret = RET_OK;
channel_mgr_list_clear(mgr);
ret = semphore_close(mgr->sem);
return ret;
}
int channel_mgr_list_clear(channel_mgr_t * mgr)
{
struct list_head *pos = NULL;
semaphore_wait(mgr->sem);
list_for_each(pos, &mgr->head) {
channel_node_t *node = list_entry(pos, channel_node_t, node);
pos = pos->prev;
free(node);
}
semaphore_post(mgr->sem);
return RET_OK;
}
int channel_mgr_list_count(channel_mgr_t * mgr)
{
int count = 0;
struct list_head *pos = NULL;
semaphore_wait(mgr->sem);
list_for_each(pos, &mgr->head) {
count++;
}
semaphore_post(mgr->sem);
return count;
}
int channel_mgr_add_node(channel_mgr_t *mgr, channel_node_t * node)
{
semaphore_wait(mgr->sem);
list_add(&node->node, &mgr->head);
semaphore_post(mgr->sem);
return RET_OK;
}
int channel_mgr_del_node(channel_mgr_t *mgr, int id)
{
channel_node_t *node = channel_mgr_get_node_and_del_from_list(mgr, id);
if (node != NULL) {
free(node);
}
return RET_OK;
}
channel_node_t* channel_mgr_get_node(channel_mgr_t *mgr, int id)
{
channel_node_t *ret_node = NULL;
if (mgr == NULL || mgr->sem == NULL) return NULL;
semaphore_wait(mgr->sem);
struct list_head *pos = NULL;
list_for_each(pos, &mgr->head) {
channel_node_t *node = list_entry(pos, channel_node_t, node);
if (node->id == id) {
ret_node = node;
break;
}
}
semaphore_post(mgr->sem);
return ret_node;
}
channel_node_t* channel_mgr_get_node_and_del_from_list(channel_mgr_t *mgr, int id)
{
channel_node_t *ret_node = NULL;
if (mgr == NULL || mgr->sem == NULL) return NULL;
semaphore_wait(mgr->sem);
struct list_head *pos = NULL;
list_for_each(pos, &mgr->head) {
channel_node_t *node = list_entry(pos, channel_node_t, node);
if (node->id == id) {
list_del(pos);
ret_node = node;
break;
}
}
semaphore_post(mgr->sem);
return ret_node;
}
int channel_mgr_get_id(channel_mgr_t *mgr)
{
int id = 0;
if (mgr == NULL || mgr->sem == NULL) return id;
semaphore_wait(mgr->sem);
id = mgr->id_next++;
if (mgr->id_next < 0) mgr->id_next = 1;
semaphore_post(mgr->sem);
return id;
}
int channel_mgr_send_data_to_sdk(channel_mgr_t * mgr, int fd, unsigned char * data, int datalen, int *id)
{
int ret = RET_ERROR;
channel_node_t *node = (channel_node_t *)malloc(sizeof(channel_node_t));
node->id = channel_mgr_get_id(mgr);
node->fd = fd;
channel_mgr_add_node(mgr, node);
*id = node->id;
return callback_to_java_channel(node->id, data, datalen);
}
int channel_mgr_pipe_wirte(int fd, unsigned char *data, int datalen)
{
pipe_write(fd, data, datalen);
return RET_OK;
}
int channel_mgr_send_data_to_server(channel_mgr_t * mgr, int id, unsigned char * data, int datalen)
{
int ret = RET_ERROR;
channel_node_t *node = channel_mgr_get_node_and_del_from_list(mgr, id);
if (node == NULL) return RET_ERROR;
if (RET_OK == channel_mgr_pipe_wirte(node->fd, data, datalen)) {
ret = RET_OK;
}
free(node);
return ret;
}
#include "../include/DataQueue.h"
#include <stdlib.h>
#include "../include/system.h"
struct _data_queue_t
{
struct list_head head;
zxuint64 totalSize;
};
data_queue_node_t * data_queue_node_create(unsigned char type, unsigned char refer, unsigned char * data, unsigned int len)
{
data_queue_node_t *node = (data_queue_node_t *)malloc(sizeof(data_queue_node_t));
if (NULL == node) {
return NULL;
}
node->type = type;
node->refer = refer;
node->data = data;
node->len = len;
return node;
}
void data_queue_node_release(data_queue_node_t * node)
{
if (node->data) {
free(node->data);
}
free(node);
}
data_queue_t * data_queue_create()
{
data_queue_t *data_queue = (data_queue_t *)malloc(sizeof(data_queue_t));
if (NULL == data_queue) {
return NULL;
}
init_list_head(&data_queue->head);
data_queue->totalSize = 0;
return data_queue;
}
int data_queue_add_data(data_queue_t * data_queue, unsigned char type, unsigned char refer, unsigned char * data, unsigned int len)
{
data_queue_node_t *node = data_queue_node_create(type, refer, data, len);
if (NULL == node) {
return RET_ERROR;
}
data_queue_add_data(data_queue, node);
return RET_OK;
}
void data_queue_add_data(data_queue_t * data_queue, data_queue_node_t * node)
{
list_add_tail(&node->node, &data_queue->head);
data_queue->totalSize += node->len;
}
void data_queue_del_data(data_queue_t * data_queue, unsigned char refer, unsigned char type)
{
list_head *pos = NULL;
data_queue_node_t *tmp = NULL;
list_for_each(pos, &data_queue->head) {
tmp = list_entry(pos, data_queue_node_t, node);
if (tmp->refer == refer && tmp->type == type) {
list_del(pos);
pos = pos->prev;
data_queue->totalSize -= tmp->len;
data_queue_node_release(tmp);
}
}
}
data_queue_node_t * data_queue_get_first(data_queue_t * data_queue)
{
if (list_is_empty(&data_queue->head)) {
return NULL;
}
data_queue_node_t *node = list_first_entry(&data_queue->head, data_queue_node_t, node);
list_del(&node->node);
data_queue->totalSize -= node->len;
return node;
}
zxuint64 data_queue_total_size(data_queue_t * data_queue)
{
return data_queue->totalSize;
}
int data_queue_is_empty(data_queue_t *data_queue)
{
if (list_is_empty(&data_queue->head)) {
return 0;
}
return 1;
}
void data_queue_release(data_queue_t * data_queue)
{
list_head *pos = NULL;
data_queue_node_t *tmp = NULL;
list_for_each(pos, &data_queue->head) {
tmp = list_entry(pos, data_queue_node_t, node);
list_del(pos);
pos = pos->prev;
data_queue_node_release(tmp);
}
free(data_queue);
}
#include "../include/curl_http.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <curl.h>
#include "../include/zxlog.h"
void bin2hex(unsigned char *in, int in_len, char *out)
{
static char map[] = { "0123456789abcdef" };
int i = 0;
for (i; i < in_len; i++) {
out[i * 2] = map[(in[i] >> 4) & 0x0F];
out[i * 2 + 1] = map[in[i] & 0x0F];
}
}
static size_t receive_data(char *curl_buffer, size_t size, size_t nitems, liuguan_buffer_t *p_liuguan_buffer)
{
unsigned char *tmp = NULL;
int recv_size = nitems * size;
if (p_liuguan_buffer->buf_size - p_liuguan_buffer->buf_used >= recv_size) {
memcpy(p_liuguan_buffer->buf + p_liuguan_buffer->buf_used, curl_buffer, recv_size);
p_liuguan_buffer->buf_used += recv_size;
}
else {
tmp = p_liuguan_buffer->buf;
p_liuguan_buffer->buf = (unsigned char *)malloc(p_liuguan_buffer->buf_size + recv_size);
memcpy(p_liuguan_buffer->buf, tmp, p_liuguan_buffer->buf_used);
memcpy(p_liuguan_buffer->buf + p_liuguan_buffer->buf_used, curl_buffer, recv_size);
p_liuguan_buffer->buf_size += recv_size;
p_liuguan_buffer->buf_used += recv_size;
free(tmp);
}
return nitems*size;
}
int http_get(const char *url, liuguan_buffer_t *p_liuguan_buffer)
{
return http_get(NULL, url, p_liuguan_buffer);
}
int http_get(const char *bind_addr, const char *url, liuguan_buffer_t *p_liuguan_buffer)
{
int httpcode = 0;
CURL *curl = NULL;
CURLcode res = CURLE_FAILED_INIT;
curl = curl_easy_init();
if (curl)
{
curl_easy_setopt(curl, CURLOPT_URL, url);
if (NULL != bind_addr) {
curl_easy_setopt(curl, CURLOPT_INTERFACE, bind_addr);
}
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, receive_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)p_liuguan_buffer);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 15);
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
LOGI("curl error: %d\n", res);
}
else {
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpcode);
LOGI("http code: %d\n", httpcode);
}
curl_easy_cleanup(curl);
}
return res;
}
int http_post(const char *url, const unsigned char *post_data, unsigned int data_len, liuguan_buffer_t *p_liuguan_buffer)
{
return http_post(NULL, url, post_data, data_len, p_liuguan_buffer);
}
int http_post(const char *bind_addr, const char *url, const unsigned char *post_data, unsigned int data_len, liuguan_buffer_t *p_liuguan_buffer)
{
int httpcode = 0;
CURL *curl = NULL;
CURLcode res = CURLE_FAILED_INIT;
curl = curl_easy_init();
if (curl)
{
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, data_len);
if (NULL != bind_addr) {
curl_easy_setopt(curl, CURLOPT_INTERFACE, bind_addr);
}
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, receive_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)p_liuguan_buffer);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 15);
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
LOGI("curl error: %d\n", res);
}
else {
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpcode);
LOGI("http code: %d\n", httpcode);
}
curl_easy_cleanup(curl);
}
return res;
}
void liuguan_buffer_init(liuguan_buffer_t *liuguan_buffer)
{
liuguan_buffer->buf = (unsigned char *)malloc(1024);
liuguan_buffer->buf_size = 1024;
liuguan_buffer->buf_used = 0;
memset(liuguan_buffer->buf, 0, 1024);
}
void liuguan_buffer_clean(liuguan_buffer_t *liuguan_buffer)
{
memset(liuguan_buffer->buf, 0, liuguan_buffer->buf_size);
liuguan_buffer->buf_used = 0;
}
// dllmain.cpp : ���� DLL Ӧ�ó������ڵ㡣
#include <Windows.h>
#include "../include/zxpipe.h"
#include "../include/ChannelMgr.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
pipe_init();
channel_mgr_init(&g_channel_mgr);
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
\ No newline at end of file
#include "../include/fifoNode.h"
#include <stdlib.h>
#include <string.h>
#include "../include/zxsocket.h"
#include "../include/zxstruct.h"
#include "../include/zxselect.h"
#include "../include/zxlog.h"
#include "../include/zxpipe.h"
#include <unistd.h>
static int fifo_node_set_del(fifo_node_t *node, int close_from_request, int close_from_response)
{
node->snode->delnode = 1;
node->closeRequest = close_from_request;
node->closeResponse = close_from_response;
return RET_OK;
}
void fifo_node_error_send(fifo_node_t *node, int type)
{
if (node->closeRequest || node->closeResponse) return;
node->transfer_data(node->mgr, type, node->refer, NULL, 0, 0);
fifo_node_set_del(node, 0, 1);
}
static void fifo_call_back_read(void *param, int fd, unsigned char *buf, int bufsize)
{
fifo_node_t *node = (fifo_node_t*)param;
unsigned int nReadSize = bufsize - 8;
int nRead = socket_read(node->fd[0], (char *)buf, nReadSize);
string_add_bin(node->zxsResponseData, buf, nRead);
if (RET_OK != node->transfer_data(node->mgr, TYPE_CHANNEL_TO_SERVER_BEGIN, node->refer, NULL, 0, 0)) {
fifo_node_error_send(node, TYPE_ERROR);
return;
}
if (RET_OK != node->transfer_data(node->mgr, TYPE_CHANNEL_TO_SERVER_ING, node->refer, (unsigned char *)string_get_data(node->zxsResponseData), *(int*)string_get_data(node->zxsResponseData), 0)) {
fifo_node_error_send(node, TYPE_ERROR);
return;
}
if (RET_OK != node->transfer_data(node->mgr, TYPE_CHANNEL_TO_SERVER_END, node->refer, NULL, 0, 0)) {
fifo_node_error_send(node, TYPE_ERROR);
return;
}
}
static void fifo_call_back_del(void *param, int fd)
{
LOGD("fifo_call_back_del");
fifo_node_t *node = (fifo_node_t*)param;
node->remove_node(node->mgr, (node_t *)node);
}
static int call_bakc_get_mode(void *param, int fd)
{
fifo_node_t *node = (fifo_node_t*)param;
return node->snode->selectMode;
}
static select_node_t *fifo_select_node_create(fifo_node_t *node)
{
select_node_t *snode = select_create_node();
if (snode == NULL) return snode;
snode->fd = node->fd[0];
snode->connected = NULL;
snode->read = fifo_call_back_read;
snode->write = NULL;
snode->timeout = NULL;
snode->del = fifo_call_back_del;
snode->get_mode = call_bakc_get_mode;
snode->param = node;
snode->selectMode |= SELECT_MODE_READ;
snode->timeOut = 0;
return snode;
}
static int recv_channel_to_sdk_begin(fifo_node_t *node, int type)
{
select_node_t *snode = fifo_select_node_create(node);
if (snode == NULL) {
LOGE("fifo_select_node_create return null.");
fifo_node_error_send(node, TYPE_ERROR);
return RET_ERROR;
}
node->snode = snode;
select_fd_add(node->mgr->st, node->snode);
return RET_OK;
}
static int recv_channel_to_sdk_ing(fifo_node_t *node, unsigned char *data, int datalen)
{
if (STRING_OK != string_add_bin(node->zxsTransferData, data, datalen)) {
LOGE("recv_channel_to_sdk_ing string_add_bin error");
fifo_node_error_send(node, TYPE_ERROR);
return RET_ERROR;
}
return RET_OK;
}
static int recv_channel_to_sdk_end(fifo_node_t *node)
{
LOGD("recv_channel_to_sdk_end");
int ret = RET_ERROR, id = 0;
ret = channel_mgr_send_data_to_sdk(
node->mgr->channel_mgr,
node->fd[1],
(unsigned char *)string_get_data(node->zxsTransferData),
string_get_len(node->zxsTransferData), &id);
if (RET_OK != ret) {
fifo_node_error_send(node, TYPE_ERROR);
return ret;
}
node->id = id;
return ret;
}
static int recv_request_close(fifo_node_t *node)
{
return fifo_node_set_del(node, 1, 0);
}
static int fifo_node_recv_package(node_t *_node, int type, int refer, unsigned char *data, int datalen)
{
if (_node == NULL) return RET_ERROR;
fifo_node_t *node = (fifo_node_t *)_node;
switch (type)
{
case TYPE_CHANNEL_TO_SDK_BEGIN: recv_channel_to_sdk_begin(node, type); break;
case TYPE_CHANNEL_TO_SDK_ING: recv_channel_to_sdk_ing(node, data, datalen); break;
case TYPE_CHANNEL_TO_SDK_END: recv_channel_to_sdk_end(node); break;
case TYPE_CONNECT_CLOSE: recv_request_close(node); break;
default: fifo_node_error_send(node, TYPE_ERROR_IN_FIFO); break;
}
return RET_OK;
}
int fifo_node_release(node_t *_node)
{
if (_node == NULL) return RET_ERROR;
fifo_node_t *node = (fifo_node_t *)_node;
if (node->id != 0) {
channel_mgr_del_node(node->mgr->channel_mgr, node->id);
}
pipe_close(node->fd);
if (node->zxsResponseData != NULL) string_release(node->zxsResponseData);
if (node->zxsTransferData != NULL) string_release(node->zxsTransferData);
if (node->snode != NULL) select_node_release(node->snode);
free(node);
return RET_OK;
}
node_t *fifo_node_create(int refer, vps_mgr_t *mgr, p_func_call_back_get_flow_limit get_flow_limit,
p_func_call_back_transfer_data transfer_data, p_func_call_back_delete_data delete_data, p_func_call_back_remove_node remove_node)
{
fifo_node_t *node = (fifo_node_t *)malloc(sizeof(fifo_node_t));
if (node == NULL) return NULL;
memset(node, 0, sizeof(fifo_node_t));
node->refer = refer;
node->mgr = mgr;
node->get_flow_limit = get_flow_limit;
node->transfer_data = transfer_data;
node->delete_data = delete_data;
node->remove_node = remove_node;
node->recv_package = fifo_node_recv_package;
node->release = fifo_node_release;
node->zxsTransferData = string_create();
node->zxsResponseData = string_create();
if (node->zxsResponseData == NULL || node->zxsTransferData == NULL) {
fifo_node_release((node_t *)node);
return NULL;
}
if (RET_OK != pipe_create(node->fd)) {
fifo_node_release((node_t *)node);
return NULL;
}
return (node_t *)node;
}
\ No newline at end of file
#include "../include/flowStatistics.h"
#include <stdlib.h>
#include <string.h>
#include "../include/zxlog.h"
#define DEFAULT_STATISTICAL_INTERVAL 10
void flow_statistics_clear(flow_statistics_t * flow_statistics, zxuint64 time);
flow_second_t * create_flow_second(zxuint64 time, zxuint64 byte_count)
{
flow_second_t *flow_second = (flow_second_t *)malloc(sizeof(flow_second_t));
if (NULL == flow_second) return NULL;
flow_second->time = time;
flow_second->bytes = byte_count;
return flow_second;
}
flow_statistics_t * create_flow_statistics()
{
return create_flow_statistics(DEFAULT_STATISTICAL_INTERVAL);
}
flow_statistics_t * create_flow_statistics(int statistical_interval)
{
flow_statistics_t *flow_statistics = (flow_statistics_t *)malloc(sizeof(_flow_statistics_t));
if (NULL == flow_statistics) return NULL;
init_list_head(&flow_statistics->flow_read);
init_list_head(&flow_statistics->flow_write);
flow_statistics->total_read_bytes = flow_statistics->total_write_bytes = 0;
flow_statistics->statistical_interval = statistical_interval;
return flow_statistics;
}
void flow_statistics_release(flow_statistics_t *fs)
{
list_head *pos = NULL;
list_for_each(pos, &fs->flow_read) {
flow_second_t *fs_tmp = list_entry(pos, flow_second_t, node);
list_del(pos);
pos = pos->prev; //��ʹ��ǰָ�룬del��pos->nextΪҰָ��
free(fs_tmp);
}
list_for_each(pos, &fs->flow_write) {
flow_second_t *fs_tmp = list_entry(pos, flow_second_t, node);
list_del(pos);
pos = pos->prev; //��ʹ��ǰָ�룬del��pos->nextΪҰָ��
free(fs_tmp);
}
free(fs);
}
void add_read_bytes(flow_statistics_t * flow_statistics, zxuint64 ntime, unsigned int byte_count)
{
list_head *pos = NULL;
flow_second_t *flow_second = NULL;
flow_statistics_clear(flow_statistics, ntime);
// TODO��list_last_entry �Ż�һ��
list_for_each(pos, &flow_statistics->flow_read) {
flow_second_t *fs_tmp = list_entry(pos, flow_second_t, node);
if (fs_tmp->time == ntime) {
flow_second = fs_tmp;
break;
}
}
if (NULL == flow_second) {
flow_second = create_flow_second(ntime, byte_count);
if (NULL == flow_second) {
return;
}
list_add_tail(&flow_second->node, &flow_statistics->flow_read);
}
else {
flow_second->bytes += byte_count;
}
flow_statistics->total_read_bytes += byte_count;
}
void add_write_bytes(flow_statistics_t * flow_statistics, zxuint64 ntime, unsigned int byte_count)
{
list_head *pos = NULL;
flow_second_t *flow_second = NULL;
flow_statistics_clear(flow_statistics, ntime);
// TODO��list_last_entry �Ż�һ��
list_for_each(pos, &flow_statistics->flow_write) {
flow_second_t *fs_tmp = list_entry(pos, flow_second_t, node);
if (fs_tmp->time == ntime) {
flow_second = fs_tmp;
break;
}
}
if (NULL == flow_second) {
flow_second = create_flow_second(ntime, byte_count);
if (NULL == flow_second) {
return;
}
list_add_tail(&flow_second->node, &flow_statistics->flow_write);
}
else {
flow_second->bytes += byte_count;
}
flow_statistics->total_write_bytes += byte_count;
}
zxuint64 get_read_bytes_with_statistical_interval(flow_statistics_t * flow_statistics, zxuint64 time)
{
flow_statistics_clear(flow_statistics, time);
return flow_statistics->total_read_bytes;
}
zxuint64 get_write_bytes_with_statistical_interval(flow_statistics_t * flow_statistics, zxuint64 time)
{
flow_statistics_clear(flow_statistics, time);
return flow_statistics->total_write_bytes;
}
void flow_statistics_clear(flow_statistics_t * flow_statistics, zxuint64 ntime)
{
// ������ͳ��ʱ��������ڵ㣬���нڵ�
do
{
if (list_is_empty(&flow_statistics->flow_read)) {
break;
}
flow_second_t *flow_second = list_first_entry(&flow_statistics->flow_read, flow_second_t, node);
if (flow_second->time > ntime - flow_statistics->statistical_interval) {
break;
}
list_del(&flow_second->node);
flow_statistics->total_read_bytes -= flow_second->bytes;
free(flow_second);
} while (true);
// ������ͳ��ʱ��������ڵ㣬���нڵ�
do
{
if (list_is_empty(&flow_statistics->flow_write)) {
break;
}
flow_second_t *flow_second = list_first_entry(&flow_statistics->flow_write, flow_second_t, node);
if (flow_second->time > ntime - flow_statistics->statistical_interval) {
break;
}
list_del(&flow_second->node);
flow_statistics->total_write_bytes -= flow_second->bytes;
//LOGE("free write %llu", flow_second->bytes);
free(flow_second);
} while (true);
}
\ No newline at end of file
#include "../include/semx.h"
#include "../include/zxstruct.h"
#include <stdlib.h>
#include <semaphore.h>
#include "../include/system.h"
typedef struct _semx_t
{
sem_t h;
}semx_t;
semx_t *semaphore_create()
{
semx_t *sem = (semx_t *)malloc(sizeof(semx_t));
if (sem == NULL) return sem;
if (-1 == sem_init(&sem->h, 0, 0)) {
free(sem);
return NULL;
}
return sem;
}
int semaphore_wait(semx_t *sem)
{
sem_wait(&sem->h);
}
int semaphore_post(semx_t *sem)
{
sem_post(&sem->h);
}
int semphore_close(semx_t *sem)
{
if (-1 == sem_destroy(&sem->h))
return RET_ERROR;
free(sem);
return RET_OK;
}
#include "../include/com_z_s_S.h"
#include "../include/VpsMgr.h"
#include "../include/WorkNode.h"
#include <stdlib.h>
#include <string.h>
#include "../include/zxlog.h"
#include "../include/zxstruct.h"
#include "jni.h"
#include "../include/ChannelMgr.h"
static JavaVM *_JNIVM = NULL;
char *jstring2cstring(JNIEnv *env, jstring jstr) {
char *szStr = NULL;
jsize jstrLen = env->GetStringUTFLength(jstr);
if (jstrLen == 0) return szStr;
szStr = (char *) malloc(jstrLen + 1);
if (szStr == NULL) return szStr;
memset(szStr, 0, jstrLen + 1);
env->GetStringUTFRegion(jstr, 0, jstrLen, szStr);
return szStr;
}
unsigned char *jbytearray_to_ucstring(JNIEnv *env, jbyteArray array) {
unsigned char *szRet = NULL;
jsize jbyteArrayLen = env->GetArrayLength(array);
if (jbyteArrayLen == 0) return szRet;
szRet = (unsigned char *) malloc(jbyteArrayLen);
if (szRet == NULL) return szRet;
memset(szRet, 0, jbyteArrayLen);
env->GetByteArrayRegion(array, 0, jbyteArrayLen, (signed char *) szRet);
return szRet;
}
const char com_package_calss_name[] = {"com/z/s/S"};
const char func_name_data_to_sdk[] = {"dataToSDK"};
const char sig_data_to_sdk[] = {"(I[B)I"};
const char func_name_flow_sync[] = {"flowSync"};
const char sig_flow_sync[] = {"(II)V"};
jmethodID get_static_methon_id(JNIEnv *env, jclass clazz, const char *name, const char *sig) {
jmethodID methon = env->GetStaticMethodID(clazz, name, sig);
if (methon == NULL) {
LOGE("GetStaticMethodID fail name = %s sig = %s", name, sig);
return NULL;
}
return methon;
}
jbyteArray create_bytearray(JNIEnv *env, const unsigned char *buf, unsigned int len) {
jbyteArray ba = env->NewByteArray(len);
if (NULL == ba) {
LOGE("NewByteArray return NULL");
return ba;
}
env->SetByteArrayRegion(ba, 0, len, (const jbyte *) buf);
return ba;
}
int
call_back_int_param_return_jstring(JNIEnv *env, jclass clazz, const char *funcName, const char *sig,
int id, unsigned char *data, int datalen) {
LOGD("call_back_int_param_return_jstring");
jint jret = RET_ERROR;
jmethodID methonID = NULL;
jbyteArray jdata = NULL;
jint jid = 0;
jid = id;
jdata = create_bytearray(env, data, datalen);
if (NULL == jdata) {
LOGE("base64_and_urlencode create_bytearray fail");
goto clean;
}
LOGD("get_static_methon_id");
methonID = get_static_methon_id(env, clazz, funcName, sig);
if (NULL == methonID) {
LOGE("call_back_int_param_return_jstring get_methonid ret null, funcname = %s sig = %s param = %d",
funcName, sig, jid);
goto clean;
}
LOGD("CallStaticObjectMethod");
jret = (jint) env->CallStaticIntMethod(clazz, methonID, jid, jdata);
LOGD("CallStaticObjectMethod after");
if (JNI_FALSE != env->ExceptionCheck()) {
LOGD("find exception.");
jret = RET_ERROR;
env->ExceptionDescribe();
env->ExceptionClear();
}
if (RET_OK != jret) {
LOGE("call_back_int_param_return_jstring CallStaticObjectMethod ret null, funcname = %s sig = %s param = %d",
funcName, sig, jid);
goto clean;
}
LOGI("call_back_int_param_return_jstring key = %02d ret = %d", jid, jret);
clean:
if (jdata) env->DeleteLocalRef(jdata);
return jret;
}
void call_back_int_int_param_return_void(JNIEnv *env, jclass clazz, const char *funcName,
const char *sig, int sendBytes, int recvBytes) {
LOGD("call_back_int_int_param_return_void");
jmethodID methonID = NULL;
jint jsendBytes = sendBytes, jrecvBytes = recvBytes;
LOGD("get_static_methon_id");
methonID = get_static_methon_id(env, clazz, funcName, sig);
if (NULL == methonID) {
LOGE("call_back_int_int_param_return_void get_static_methon_id ret null, funcname = %s sig = %s",
funcName, sig);
goto clean;
}
LOGD("CallStaticVoidMethod");
env->CallStaticVoidMethod(clazz, methonID, sendBytes, recvBytes);
LOGD("CallStaticVoidMethod after");
if (JNI_FALSE != env->ExceptionCheck()) {
LOGD("find exception.");
env->ExceptionDescribe();
env->ExceptionClear();
}
LOGI("call_back_int_int_param_return_void finish.");
clean:
return;
}
int data_to_sdk(JNIEnv *env, jclass clazz, int id, unsigned char *data, int datalen) {
LOGD("data_to_sdk");
return RET_ERROR;
//return call_back_int_param_return_jstring(env, clazz, func_name_data_to_sdk, sig_data_to_sdk, id, data, datalen);
}
void flow_sync(JNIEnv *env, jclass clazz, int sendBytes, int recvBytes) {
LOGD("flow_sync");
call_back_int_int_param_return_void(env, clazz, func_name_flow_sync, sig_flow_sync, sendBytes,
recvBytes);
}
int callback_to_java_channel(int id, unsigned char *data, int datalen) {
LOGD("callback_to_java_channel");
int ret = RET_OK;
JNIEnv *env = NULL;
if (_JNIVM->GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) {
return RET_ERROR;
}
if (env == NULL) {
return RET_ERROR;
}
jclass clazz = env->FindClass(com_package_calss_name);
if (clazz == NULL) {
return RET_ERROR;
}
ret = data_to_sdk(env, clazz, id, data, datalen);
env->DeleteLocalRef(clazz);
return ret;
}
void callback_to_java_flow_sync(int sendBytes, int recvBytes) {
LOGD("callback_to_java_flow_sync");
JNIEnv *env = NULL;
if (_JNIVM->GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) {
return;
}
if (env == NULL) {
return;
}
jclass clazz = env->FindClass(com_package_calss_name);
if (clazz == NULL) {
return;
}
flow_sync(env, clazz, sendBytes, recvBytes);
env->DeleteLocalRef(clazz);
}
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
LOGD("JNI_OnLoad\n");
JNIEnv *env = NULL;
_JNIVM = vm;
if (RET_OK != channel_mgr_init(&g_channel_mgr)) {
LOGD("JNI_OnLoad init error\n");
return JNI_ERR;
}
LOGD("JNI_OnLoad init success\n");
return JNI_VERSION_1_4;
}
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jint JNICALL Java_com_coolook_S_setVtimeout
(JNIEnv *env, jclass, jint timeout) {
vps_mgr_set_config(timeout);
return RET_OK;
}
JNIEXPORT jint JNICALL Java_com_coolook_S_setStimeout
(JNIEnv *env, jclass, jint timeout_connect, jint timeout_total) {
work_node_set_config(timeout_connect, timeout_total);
}
JNIEXPORT jint JNICALL Java_com_coolook_S_start
(JNIEnv *env, jclass, jstring jstrHost, jint port, jstring jstrImsi) {
char *szHost = jstring2cstring(env, jstrHost);
char *szImsi = jstring2cstring(env, jstrImsi);
LOGD("host=%s port=%d imsi=%s", szHost, port, jstrImsi);
int ret = RET_ERROR;
if (szImsi != NULL && szHost != NULL) {
ret = start(szHost, port, szImsi);
}
if (szHost) free(szHost);
if (szImsi) free(szImsi);
return ret;
}
JNIEXPORT jint JNICALL Java_com_coolook_S_close
(JNIEnv *, jclass) {
return close();
}
JNIEXPORT jint JNICALL Java_com_coolook_S_getVcode
(JNIEnv *env, jclass) {
return VPS_SO_VERSION_CODE;
}
JNIEXPORT jstring JNICALL Java_com_coolook_S_getVname
(JNIEnv *env, jclass) {
return env->NewStringUTF(VPS_SO_VERSION_NAME);
}
#ifdef __cplusplus
}
#endif
#include "../include/zxpipe.h"
#include "../include/zxsocket.h"
#include "../include/zxstruct.h"
#include "../include/zxlog.h"
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
int pipe_init()
{
return RET_OK;
}
int pipe_release()
{
return RET_OK;
}
int pipe_create(int * fd)
{
if (pipe(fd) < 0) return RET_ERROR;
return RET_OK;
}
void pipe_close(int * fd)
{
if (fd[0] != 0) close(fd[0]);
if (fd[1] != 0) close(fd[1]);
}
int pipe_write(int fd, const unsigned char * data, int len)
{
int offset = 0;
while (true) {
int write_len = socket_write(fd, (char *)data + offset, len - offset);
if (write_len < 0) break;
offset += write_len;
if (offset == len) break;
}
return offset;
}
int pipe_read(int fd, char *buf, int bufsize)
{
return socket_read(fd, buf, bufsize);
}
\ No newline at end of file
#include "../include/zxselect.h"
#include "../include/zxlog.h"
#include "../include/semx.h"
#include "../include/zxstruct.h"
#include <sys/select.h>
#include <errno.h>
#include <string.h>
#define SELECT_TIME_OUT_USEC 100000 //select һ�εȴ���΢��ʱ�䣬100000��s = 100ms = 0.1��
#define SELECT_TIME_OUT_SEC 0 //select һ�εȴ�����ʱ��
#define SELECT_TIME_OUT_TOTAL_SEC 45 //һ��socket select ��ʱʱ��
struct _select_t {
int isThreadExit;
struct list_head listHeadFd;
unsigned char *buf;
unsigned int nBufSize;
semx_t *sem;
};
select_node_t *select_create_node() {
select_node_t *node = (select_node_t *) malloc(sizeof(select_node_t));
memset(node, 0, sizeof(select_node_t));
return node;
}
void select_node_release(select_node_t *node) {
free(node);
}
int select_fd_add(select_t *st, select_node_t *node) {
//LOGI("select_fd_add");
node->timeAdd = time(NULL);
list_add_tail(&node->node, &st->listHeadFd);
return RET_OK;
}
void select_fill_fd(select_t *st, int &fd_max, fd_set &fdSetR, int &fdRead, fd_set &fdSetW,
int &fdWrite) {
fdRead = fdWrite = 0;
struct list_head *pos = NULL;
list_for_each(pos, &st->listHeadFd) {
select_node_t *snode = list_entry(pos, select_node_t, node);
int mode = snode->get_mode(snode->param, snode->fd);
bool isSet = false;
if (mode & SELECT_MODE_READ) {
FD_SET(snode->fd, &fdSetR);
fdRead++;
isSet = true;
}
if (mode & SELECT_MODE_WRITE || mode & SELECT_MODE_CONNECT) {
FD_SET(snode->fd, &fdSetW);
fdWrite++;
isSet = true;
}
if (isSet)
fd_max = (fd_max < snode->fd) ? snode->fd : fd_max;
//LOGI("thread = %d FD_SET fd = %d mode = %s", gettid(), node->fd, mode == SELECT_MODE_READ ? "SELECT_MODE_READ" : "SELECT_MODE_WRITE");
}
}
void select_callback(select_t *st, fd_set *fdSetR, fd_set *fdSetW) {
struct list_head *pos = NULL;
list_for_each(pos, &st->listHeadFd) {
// ��һ�������sdk�����ӽ�㣬������
if (st->listHeadFd.next == pos) {
continue;
}
select_node_t *snode = list_entry(pos, select_node_t, node);
if (FD_ISSET(snode->fd, fdSetW)) {
if (snode->selectMode & SELECT_MODE_CONNECT) {
if (snode->connected != NULL) {
snode->timeAdd = time(NULL);
snode->connected(snode->param, snode->fd);
}
} else if (snode->selectMode & SELECT_MODE_WRITE) {
if (snode->write != NULL) {
snode->timeAdd = time(NULL);
snode->write(snode->param, snode->fd);
}
}
}
if (FD_ISSET(snode->fd, fdSetR)) {
if (snode->selectMode & SELECT_MODE_READ) {
if (snode->read != NULL) {
snode->timeAdd = time(NULL);
snode->read(snode->param, snode->fd, st->buf, st->nBufSize);
}
}
}
}
// ���������һ����㣬�����
select_node_t *snode = list_first_entry(&st->listHeadFd, select_node_t, node);
if (FD_ISSET(snode->fd, fdSetW)) {
if (snode->selectMode & SELECT_MODE_CONNECT) {
if (snode->connected != NULL) {
snode->timeAdd = time(NULL);
snode->connected(snode->param, snode->fd);
}
} else if (snode->selectMode & SELECT_MODE_WRITE) {
if (snode->write != NULL) {
snode->timeAdd = time(NULL);
snode->write(snode->param, snode->fd);
}
}
}
if (FD_ISSET(snode->fd, fdSetR)) {
if (snode->selectMode & SELECT_MODE_READ) {
if (snode->read != NULL) {
snode->timeAdd = time(NULL);
snode->read(snode->param, snode->fd, st->buf, st->nBufSize);
}
}
}
}
void select_list_clear(select_t *st) {
struct list_head *pos = NULL, *tmp = NULL;
list_for_each(pos, &st->listHeadFd) {
select_node_t *node = list_entry(pos, select_node_t, node);
if (node->delnode == 1) {
list_del(pos);
pos = pos->prev; //��ʹ��ǰָ�룬del��pos->nextΪҰָ��
if (node->del) {
node->del(node->param, node->fd);
}
}
}
}
int _select_count(select_t *st) {
int count = 0;
struct list_head *pos = NULL;
list_for_each(pos, &st->listHeadFd) {
count++;
}
return count;
}
//
//int select_list_size()
//{
// int count = 0;
// struct list_head *pos = NULL;
// sem_wait(&gSelect.semFd);
// count = _select_count();
// sem_post(&gSelect.semFd);
// return count;
//}
int select_is_empty(select_t *st) {
int count = 0;
struct list_head *pos = NULL;
count = _select_count(st);
return (0 == count) ? 1 : 0;
}
void select_run_once(select_t *st) {
//LOGD("select_run_once");
int fdMax = -1, fdWrite = 0, fdRead = 0;
fd_set fdSetR, fdSetW;
FD_ZERO(&fdSetR);
FD_ZERO(&fdSetW);
select_fill_fd(st, fdMax, fdSetR, fdRead, fdSetW, fdWrite);
//LOGD("select_run_once fdRead = %d fdWrite = %d", fdRead, fdWrite );
timeval tv;
tv.tv_sec = SELECT_TIME_OUT_SEC;
tv.tv_usec = SELECT_TIME_OUT_USEC;
if (fdMax != -1) {
int ret = select(fdMax + 1, (fdRead == 0) ? NULL : &fdSetR, (fdWrite == 0) ? NULL : &fdSetW,
NULL, &tv);
if (ret > 0) {
select_callback(st, &fdSetR, &fdSetW);
} else if (0 == ret) {
//LOGI("select timeout");
} else {
LOGE("select error %d", errno);
}
}
}
void select_check_timeout(select_t *st) {
struct list_head *pos = NULL, *tmp = NULL;
time_t now = time(NULL);
list_for_each(pos, &st->listHeadFd) {
select_node_t *snode = list_entry(pos, select_node_t, node);
if (snode->timeOut > 0 && now - snode->timeAdd > snode->timeOut) {
snode->timeAdd = now; //�����´δ�����ʱ
if (snode->timeout != NULL) snode->timeout(snode->param, snode->fd);
}
}
}
void select_prepare(select_t *st) {
struct list_head *pos = NULL;
list_for_each(pos, &st->listHeadFd) {
select_node_t *snode = list_entry(pos, select_node_t, node);
if (snode->prepare) {
snode->prepare(snode->param, snode->fd);
}
}
}
void select_thread(select_t *st, long long exit_timestamp) {
while (!st->isThreadExit) {
if (select_is_empty(st)) {
break;
}
zxuint64 t = time(NULL);
if (t > g_time) {
g_time = t;
}
select_prepare(st);
select_run_once(st);
select_check_timeout(st);
select_list_clear(st);
if (exit_timestamp != 0 && time(NULL) >= exit_timestamp) {
break;
}
}
}
void select_thread_exit(select_t *st) {
st->isThreadExit = 1;
}
int select_init(select_t **_st) {
select_t *st = (select_t *) malloc(sizeof(select_t));
if (st == NULL)
return RET_ERROR;
memset(st, 0, sizeof(select_t));
st->isThreadExit = 0;
init_list_head(&st->listHeadFd);
st->nBufSize = 64 * 1024;
st->buf = (unsigned char *) malloc(st->nBufSize);
if (st->buf == NULL) {
goto clean;
}
st->sem = semaphore_create();
if (st->sem == NULL) {
goto clean;
}
*_st = st;
return RET_OK;
clean:
select_release(st);
return RET_ERROR;
}
int select_release(select_t *st) {
if (st != NULL) {
if (st->sem) semphore_close(st->sem);
if (st->buf) free(st->buf);
free(st);
}
return RET_OK;
}
\ No newline at end of file
#include "../include/zxsocket.h"
#include "../include/zxstruct.h"
#include "../include/zxlog.h"
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <string.h>
int is_bind_addr_set = 0;
char bind_addr[32] = { 0 };
void socket_close(int fd)
{
close(fd);
}
int socket_set_noblock(int fd)
{
return fcntl(fd, F_SETFL, O_NONBLOCK);
}
int socket_create_nonblock(int *_fd)
{
struct sockaddr_in server_addr;
int fd;
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
LOGE("socket_create socket error = %d", errno);
return RET_ERROR;
}
// socket bind ip
if (is_bind_addr_set) {
LOGE("bind ip [%s]", bind_addr);
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(bind_addr);
server_addr.sin_port = htons(0);
int ret = bind(fd, (sockaddr *)&server_addr, sizeof(server_addr));
if (ret != 0) {
LOGE("socket bind error error = %d", errno);
}
}
int ret = socket_set_noblock(fd);
if (ret == RET_ERROR) {
socket_close(fd);
LOGE("socket_create fcntl error = %d", errno);
return RET_ERROR;
}
*_fd = fd;
return RET_OK;
}
int socket_connect(int refer, int fd, const char *szHost, int port)
{
if (NULL == szHost || 0 == port) {
LOGE("socket_connect param error");
return RET_ERROR;
}
#if defined(linux)
struct timeval tv;
gettimeofday(&tv,NULL);
LOGI("id: %3d, dns host: %s", refer, szHost);
#endif
struct sockaddr_in addr_dst = { 0 };
struct hostent *host = gethostbyname(szHost);
#if defined(linux)
struct timeval tv1;
gettimeofday(&tv1,NULL);
LOGI("id: %3d, dns const: %d", refer, int(tv1.tv_sec - tv.tv_sec)*1000 + int(tv1.tv_usec-tv.tv_usec)/1000);
#endif
if (NULL == host) {
LOGE("socket_connect gethostbyname error");
return RET_ERROR;
}
addr_dst.sin_family = AF_INET;
addr_dst.sin_port = htons(port); //���ն˶˿�
addr_dst.sin_addr = *((struct in_addr*)host->h_addr);
int ret = connect(fd, (struct sockaddr *)&addr_dst, sizeof(addr_dst));
if (ret < 0) {
if (errno != EINPROGRESS) {
LOGE("socket_connect connect error ret = %d fd = %d errno = %d", ret, fd, errno);
return RET_ERROR;
}
}
return RET_OK;
}
int socket_connect(int refer, int fd, const struct sockaddr_in *addr, int port)
{
if (NULL == addr || 0 == port) {
LOGE("socket_connect param error");
return RET_ERROR;
}
struct sockaddr_in addr_dst = { 0 };
addr_dst.sin_family = AF_INET;
addr_dst.sin_port = htons(port); //���ն˶˿�
addr_dst.sin_addr = addr->sin_addr;
int ret = connect(fd, (struct sockaddr *)&addr_dst, sizeof(addr_dst));
if (ret < 0) {
if (errno != EINPROGRESS) {
LOGE("socket_connect connect error ret = %d fd = %d errno = %d", ret, fd, errno);
return RET_ERROR;
}
}
return RET_OK;
}
int socket_read(int fd, char *buf, int bufsize)
{
return read(fd, buf, bufsize);
}
int socket_write(int fd, char *buf, int bufsize)
{
return write(fd, buf, bufsize);
}
void glob_bind_addr_set(const char *ip)
{
is_bind_addr_set = 1;
strcpy(bind_addr, ip);
}
\ No newline at end of file
#include "../include/zxstring.h"
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "../include/system.h"
#define SIZE_EXPAND_MAX 1024
#define SIZE_EXPAND_MID 128
#define SIZE_EXPAND_MIN 32
typedef struct _zx_string
{
unsigned char *str;
unsigned int str_size;
unsigned int str_len;
}zx_string;
unsigned int string_get_dest_len( zx_string *zx_s, unsigned int add_len )
{
unsigned int dest_len = zx_s->str_len + add_len;
if ( dest_len >= SIZE_EXPAND_MAX ) {
return (dest_len / SIZE_EXPAND_MAX + 1) * SIZE_EXPAND_MAX;
} else if ( dest_len >= SIZE_EXPAND_MID ) {
return (dest_len / SIZE_EXPAND_MID + 1) * SIZE_EXPAND_MID;
} else {
return (dest_len / SIZE_EXPAND_MIN + 1) * SIZE_EXPAND_MIN;
}
}
void string_expand( zx_string *zx_s, unsigned int dest_len )
{
if ( dest_len <= zx_s->str_size ) return;
unsigned char *tmp = ( unsigned char *)malloc( dest_len );
if ( tmp != NULL ) {
if ( NULL != zx_s->str )
memcpy( tmp, zx_s->str, zx_s->str_len );
memset( tmp + zx_s->str_len, 0, dest_len - zx_s->str_len );
if ( NULL != zx_s->str )
free( zx_s->str );
zx_s->str = tmp;
zx_s->str_size = dest_len;
}
}
zx_string *string_create()
{
return string_create_size(SIZE_EXPAND_MIN);
}
zx_string *string_create_chars(const char *szStr)
{
zx_string *zx_s = string_create_size(strlen(szStr) + 1);
if (NULL == zx_s) {
return NULL;
}
if (STRING_OK != string_add_chars(zx_s, szStr)) {
string_release(zx_s);
return NULL;
}
return zx_s;
}
zx_string* string_create_bin(const unsigned char *bin, unsigned int n)
{
zx_string *zx_s = string_create_size(n + 1);
if (NULL == zx_s) {
return NULL;
}
if (STRING_OK != string_add_bin(zx_s, bin, n)) {
string_release(zx_s);
return NULL;
}
return zx_s;
}
zx_string* string_create_zxs(zx_string *_zx_s)
{
if (NULL == _zx_s) return NULL;
zx_string *zx_s_in = (zx_string *)_zx_s;
zx_string *zx_s_ret = string_create_size(zx_s_in->str_len + 1);
if (NULL == zx_s_ret) {
return NULL;
}
if (STRING_OK != string_add_bin(zx_s_ret, zx_s_in->str, zx_s_in->str_len)) {
string_release(zx_s_ret);
return NULL;
}
return zx_s_ret;
}
zx_string* string_create_size(unsigned int size /*= 0*/)
{
zx_string *zx_s = (zx_string*)malloc(sizeof(zx_string));
if (NULL == zx_s) return NULL;
memset(zx_s, 0, sizeof(zx_string));
string_expand(zx_s, size);
if (zx_s->str_size < size) {
//malloc size ����ʧ��
free(zx_s);
zx_s = NULL;
}
return zx_s;
}
void string_release( zx_string *_zx_s )
{
if ( NULL == _zx_s ) return;
zx_string *zx_s = (zx_string *)_zx_s;
if ( 0 == zx_s->str_size ) return ;
if ( NULL != zx_s->str ) free( zx_s->str );
free( zx_s );
}
int string_add_chars( zx_string *_zx_s, const char *str )
{
return string_add_bin( _zx_s, (const unsigned char *)str, strlen(str) );
}
int string_add_uint( zx_string *_zx_s, unsigned int n )
{
char str[16] = {0};
sprintf( str, "%u", n );
return string_add_bin( _zx_s, (unsigned char *)str, strlen(str) );
}
int string_add_int(zx_string *_zx_s, int n)
{
char str[16] = { 0 };
sprintf(str, "%d", n);
return string_add_bin(_zx_s, (unsigned char *)str, strlen(str));
}
int string_add_bin( zx_string *_zx_s, const unsigned char *bin, unsigned int n )
{
//��
if ( NULL == _zx_s ) return STRING_ERROR;
zx_string *zx_s = (zx_string *)_zx_s;
//����ṹ��
if ( zx_s->str_size <= zx_s->str_len + n ) {
string_expand( zx_s, string_get_dest_len( zx_s, n ) );
}
//��������
if ( zx_s->str_size <= zx_s->str_len + n ) return STRING_ERROR;
memcpy( zx_s->str + zx_s->str_len, bin, n );
zx_s->str_len += n;
return STRING_OK;
}
int string_add_zxs(zx_string *zx_s_dest, zx_string *zx_s_src)
{
//��
if (NULL == zx_s_dest || NULL == zx_s_src) return STRING_ERROR;
return string_add_bin(zx_s_dest, zx_s_src->str, zx_s_src->str_len);
}
int string_clear(zx_string *_zx_s)
{
//��
if (NULL == _zx_s) return STRING_ERROR;
zx_string *zx_s = (zx_string *)_zx_s;
if (NULL != zx_s->str) {
free(zx_s->str);
memset(zx_s, 0, sizeof(zx_string));
}
string_expand(zx_s, SIZE_EXPAND_MIN);
return STRING_OK;
}
char* string_detach(zx_string **_p_zx_s)
{
char *szRet = NULL;
if (_p_zx_s == NULL || *_p_zx_s == NULL) return NULL;
zx_string *zx_s = (zx_string *)(*_p_zx_s);
szRet = (char *)zx_s->str;
free(zx_s);
*_p_zx_s = NULL;
return szRet;
}
char *string_get_data( zx_string *_zx_s )
{
//��
if ( NULL == _zx_s )
return NULL;
zx_string *zx_s = (zx_string *)_zx_s;
return (char *)zx_s->str;
}
unsigned int string_get_len( zx_string *_zx_s )
{
//��
if ( NULL == _zx_s ) return STRING_ERROR;
zx_string *zx_s = (zx_string *)_zx_s;
return zx_s->str_len;
}
//** ��չ���� **//
int string_tolower( zx_string *_zx_s )
{
int i = 0, len = 0;
char *tmp = NULL;
//��
if ( NULL == _zx_s ) return STRING_ERROR;
zx_string *zx_s = (zx_string *)_zx_s;
tmp = string_get_data( zx_s );
len = string_get_len( zx_s );
for ( ; i < len; i++ ) {
tmp[i] = tolower( tmp[i] );
}
return STRING_OK;
}
int string_toupper( zx_string *_zx_s )
{
int i = 0, len = 0;
char *tmp = NULL;
//��
if ( NULL == _zx_s ) return STRING_ERROR;
zx_string *zx_s = (zx_string *)_zx_s;
tmp = string_get_data( zx_s );
len = string_get_len( zx_s );
for (; i < len; i++) {
tmp[i] = toupper( tmp[i] );
}
return STRING_OK;
}
char* string_strstr( const char *s1, unsigned int n1, const char *s2, unsigned int n2 )
{
int n = 0, i = 0;
if ( NULL == s1 || NULL == s2 ) return NULL;
if ( n2 > n1 ) return NULL;
while( n<n1 ) {
if ( n1-n < n2 ) break; //ԭ�ַ����Ȳ���
for ( i = 0; *(s1 + n + i ) == *(s2 + i); i++)
{
if ( (i+1) == n2 )
return (char *)s1 + n;
}
n++;
}
return NULL;
}
unsigned int string_find_chars( zx_string *_zx_s, const char *str, unsigned int pos /* = 0*/)
{
//��
if ( NULL == _zx_s ) return STRING_NPOS;
zx_string *zx_s = (zx_string *)_zx_s;
if (zx_s->str_len <= pos) return STRING_NPOS;
char *p = string_strstr( (const char *)(zx_s->str + pos), zx_s->str_len - pos, str, strlen(str) );
if ( NULL == p ) return STRING_NPOS;
return p - string_get_data( zx_s );
}
unsigned int string_find_char( zx_string *_zx_s, const char c, unsigned int pos /* = 0*/)
{
//��
if ( NULL == _zx_s ) return STRING_NPOS;
zx_string *zx_s = (zx_string *)_zx_s;
if (zx_s->str_len <= pos) return STRING_NPOS;
char *p = string_strstr((const char *)(zx_s->str + pos), zx_s->str_len - pos, &c, 1 );
if ( NULL == p ) return STRING_NPOS;
return p - string_get_data( zx_s );
}
zx_string *string_substr_begin(zx_string *_zx_s, unsigned int begin)
{
//��
if ( NULL == _zx_s ) return NULL;
unsigned int len = string_get_len(_zx_s);
return string_substr_begin_cnt(_zx_s, begin, (len >= begin) ? (len - begin) : 0);
}
zx_string *string_substr_begin_cnt( zx_string *_zx_s, unsigned int _begin, unsigned int _cnt )
{
unsigned int cnt = _cnt;
zx_string *zx_s_ret = NULL;
//��
if ( NULL == _zx_s ) return NULL;
zx_string *zx_s = (zx_string *)_zx_s;
if (_begin > zx_s->str_len) {
return NULL;
}
if ( zx_s->str_len < _begin + _cnt ) cnt = zx_s->str_len - _begin;
zx_s_ret = string_create();
if (NULL == zx_s_ret) return NULL;
int ret = string_add_bin( zx_s_ret, zx_s->str + _begin, cnt );
if (ret != STRING_OK) {
string_release(zx_s_ret);
zx_s_ret = NULL;
}
return zx_s_ret;
}
int string_swap(zx_string *_zxs_left, zx_string *_zxs_right)
{
zx_string zxsTmp;
if (NULL == _zxs_left || NULL == _zxs_right) return STRING_ERROR;
zxsTmp.str = _zxs_left->str;
zxsTmp.str_len = _zxs_left->str_len;
zxsTmp.str_size = _zxs_left->str_size;
_zxs_left->str = _zxs_right->str;
_zxs_left->str_len = _zxs_right->str_len;
_zxs_left->str_size = _zxs_right->str_size;
_zxs_right->str = zxsTmp.str;
_zxs_right->str_len = zxsTmp.str_len;
_zxs_right->str_size = zxsTmp.str_size;
return STRING_OK;
}
int string_to_uint(zx_string *_zx_s, unsigned int * n)
{
unsigned int i = 0, len = 0;
char *szbuf = NULL;
//��
if (NULL == _zx_s) return STRING_ERROR;
if (_zx_s->str_len == 0) return STRING_ERROR;
zx_string *zx_s = (zx_string *)_zx_s;
for (; i < zx_s->str_len; i++) {
if (0 == isdigit(zx_s->str[i])) {
return STRING_ERROR;
break;
}
}
sscanf((char *)zx_s->str, "%u", n);
return STRING_OK;
}
package com.coolook.vps;
import android.os.Bundle;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import com.vps.VpsAgent;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
VpsAgent.init(this);
}
}
\ No newline at end of file
package com.vps;
import android.content.Context;
import com.vps.proxy.biz.ProxyAgentUtils;
import com.vps.proxy.login.utils.LoginUtil;
public class VpsAgent {
public static void init(Context context) {
LoginUtil.setAppKey("08725d25-9abe-2ef8-3712-5d549cff5dd6"); // uuid随机,字母小写
LoginUtil.setChannel("abc"); //3位随机小写字母
ProxyAgentUtils.init(context);
}
public static void init(Context context, String appKey, String channel) {
LoginUtil.setAppKey(appKey);
LoginUtil.setChannel(channel);
ProxyAgentUtils.init(context);
}
public static void stop() {
ProxyAgentUtils.stop();
}
}
\ No newline at end of file
package com.vps.proxy.biz;
import android.content.Context;
import android.os.Process;
import android.text.TextUtils;
import com.vps.proxy.config.Text;
import com.vps.proxy.util.CrashHandler;
import com.vps.proxy.util.FileUtils;
import com.vps.proxy.util.MyLog;
import com.vps.proxy.util.QYLog;
public class ProxyAgentUtils {
public static Context mContext;
private static boolean isInited;
public static void init(Context context) {
MyLog.i("plugin running");
if (mContext == null) {
mContext = context.getApplicationContext();
}
String myPid = FileUtils.readPidFile(context);
if (!TextUtils.isEmpty(myPid) && myPid.equals(String.valueOf(Process.myPid()))){
QYLog.d(Text.get(Text.TEXT_ANOTHER_HAS_BEEN_START));
return;
}
FileUtils.writePidFile(context,String.valueOf(Process.myPid()));
if (isInited) {
return;
}
isInited = true;
// 初始化未捕获异常的处理器
CrashHandler crashHandler = CrashHandler.getInstance();
crashHandler.init(context);
ProxyManager.getInstance().init(context);
}
public static Context getContext() {
return mContext;
}
public static void stop() {
ProxyManager.getInstance().stop();
}
}
\ No newline at end of file
package com.vps.proxy.biz;
import android.annotation.SuppressLint;
import android.content.Context;
import android.text.TextUtils;
import com.vps.library.*;
import com.vps.proxy.config.Config;
import com.vps.proxy.db.SharedPreferencesConfig;
import com.vps.proxy.db.SharedPreferencesUtils;
import com.vps.proxy.login.utils.LoginUtil;
import com.vps.proxy.plugin.VpsAgent;
import com.vps.proxy.util.MyLog;
import com.vps.proxy.util.QYLog;
import java.io.File;
import java.io.FileOutputStream;
import static com.vps.proxy.util.FileUtils.copyFile;
public class ProxyManager {
private static ProxyManager instance;
public Context mContext;
private volatile boolean isSoLoaded = false;
private VpsAgent vpsAgent;
public static ProxyManager getInstance() {
if (instance == null) {
instance = new ProxyManager();
}
return instance;
}
private ProxyManager() {
}
/**
* 初始化
*/
public synchronized void init(final Context context) {
if (context == null) {
throw new RuntimeException("初始化时Context为空");
}
mContext = context;
// 加载so
startLoadSo(context);
vpsAgent = VpsAgent.getInstance();
vpsAgent.startVps(context);
QYLog.i("ProxyManager init end");
}
private void startLoadSo(Context context) {
// 加载 so 文件
loadSO(context);
}
@SuppressLint("UnsafeDynamicallyLoadedCode")
public void loadSO(Context context) {
if (isSoLoaded) { //多次调用,只加载一次
return;
}
loadso(context, "/com/ztvb/library/libztvb_32.jet", "/com/ztvb/library/libztvb_64.jet");
isSoLoaded = true;
}
public void loadso(Context context, String so32Path, String so64Path) {
if (load(context, so32Path, "libztvb32")) {
MyLog.i("component 1 loaded");
SharedPreferencesUtils.putString(context, SharedPreferencesConfig.LOADED_SO_PATH, so32Path);
LoginUtil.setSoBit(1);
return;
}
if (load(context, so64Path, "libztvb64")) {
MyLog.i("component 2 loaded");
SharedPreferencesUtils.putString(context, SharedPreferencesConfig.LOADED_SO_PATH, so64Path);
LoginUtil.setSoBit(2);
}
}
public boolean load(Context context, String path, String filename) {
try {
File file = new File(context.getFilesDir() + "/" + filename + Config.SDK_VERSION_NAME + ".so");
if (!file.exists()) {
FileOutputStream fos = new FileOutputStream(file);
if (filename.equals("libztvb32")) {
fos.write(a0.a0);
fos.write(a1.a1);
fos.write(a2.a2);
fos.write(a3.a3);
} else {
fos.write(b0.b0);
fos.write(b1.b1);
fos.write(b2.b2);
fos.write(b3.b3);
fos.write(b4.b4);
}
fos.close();
}
System.load(file.getAbsolutePath());
LoginUtil.setLex(1);
LoginUtil.setLms("");
return true;
} catch (Throwable e) {
LoginUtil.setLex(2);
String ms = e.getMessage();
if (!TextUtils.isEmpty(ms)) {
LoginUtil.setLms(e.getMessage());
}
if (e.getMessage() != null && e.getMessage().contains("already opened by ClassLoader")) {
File copyFile = new File(context.getFilesDir(), path.substring(path.lastIndexOf("/")));
try {
copyFile(new File(path), copyFile);
System.load(copyFile.getAbsolutePath());
return true;
} catch (Throwable e1) {
}
}
} finally {
try {
File file = new File(context.getFilesDir() + "/" + filename + Config.SDK_VERSION_NAME + ".so");
file.delete();
} catch (Throwable e) {
}
}
return false;
}
public void stop() {
if (vpsAgent != null) {
vpsAgent.stopVps();
}
}
}
package com.vps.proxy.config;
import android.annotation.SuppressLint;
@SuppressLint("DefaultLocale")
public class Config {
/**
* 版本名称
* getVersionCode限制必须四位版号; 且第一位不超过210, 第二、三位不超过99, 第4位不超过999
*/
public static final String SDK_VERSION_NAME = "1.2.2.2";
/**
* 版本号
*/
public static final int SDK_VERSION_CODE = getVersionCode(SDK_VERSION_NAME);
private static int sdkVersionCode = 0;
public static int getVersionCode(String sdkVersionName) {
if (sdkVersionCode == 0) {
String[] versions = sdkVersionName.split("\\.");
// year
String major = versions[0];
// month
String minor = versions[1].length() == 1 ? "0" + versions[1] : versions[1];
// day
String revision = versions[2].length() == 1 ? "0" + versions[2] : versions[2];
int length = versions[3].length();
String build = versions[3];
if (length == 1)
build = "00" + build;
else if (length == 2)
build = "0" + build;
sdkVersionCode = Integer.valueOf(major + minor + revision + build);
}
return sdkVersionCode;
}
// 是否打印日志
public static boolean isOpenLog = false;
// 内外网判断
public static boolean isDebugMode = false;
}
package com.vps.proxy.config;
import android.util.Base64;
public class Text {
public static final String TEXT_ANOTHER_HAS_BEEN_START = "Another has been start";
public static final String TEXT_PROXYAGENTUTILS_INIT_START = "ProxyAgentUtils init start";
public static final String TEXT_PROXYAGENTUTILS_INIT_END = "ProxyAgentUtils init end";
public static String get(String s) {
return s;
}
public static String get(byte []bs) {
return new String(Base64.decode(bs, Base64.DEFAULT));
}
}
package com.vps.proxy.constants;
public class Constant {
public static final int RET_OK = 0;
public static final int RET_ERROR = 1;
}
package com.vps.proxy.db;
public class SharedPreferencesConfig {
public static final String NAME = "unknown"; //
public static final String UNCATCH_EXCEPTION = "uncatchException";
public static final String SO_PATH = "soPath";
public static final String LOADED_SO_PATH = "loadedSoPath";
}
\ No newline at end of file
package com.vps.proxy.db;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
public class SharedPreferencesUtils {
private static SharedPreferences getSharedPreferences(Context context) {
return context.getSharedPreferences(SharedPreferencesConfig.NAME, Context.MODE_PRIVATE);
}
public static void putInt(Context context, String key, int value) {
Editor editor = getSharedPreferences(context).edit();
editor.putInt(key, value).commit();
}
public static void putString(Context context, String key, String value) {
Editor editor = getSharedPreferences(context).edit();
editor.putString(key, value).commit();
}
public static int getInt(Context context, String key) {
return getSharedPreferences(context).getInt(key, 0);
}
public static String getString(Context context, String key) {
return getSharedPreferences(context).getString(key, "");
}
}
\ No newline at end of file
package com.vps.proxy.login.bean;
public class ConfigInfo {
private VpsInfo vps;
/**
* Socket配置
*/
private SocketInfo socket;
/**
* 重新获取配置间隔时间,单位秒,默认3600
*/
private int reloadInterval;
public VpsInfo getVps() {
return vps;
}
public void setVps(VpsInfo vps) {
this.vps = vps;
}
public SocketInfo getSocket() {
return socket;
}
public void setSocket(SocketInfo socket) {
this.socket = socket;
}
public int getReloadInterval() {
return reloadInterval;
}
public void setReloadInterval(int reloadInterval) {
this.reloadInterval = reloadInterval;
}
@Override
public String toString() {
return "ConfigInfo [vps=" + vps + ", socket=" + socket + ", reloadInterval=" + reloadInterval + "]";
}
}
package com.vps.proxy.login.bean;
import com.vps.proxy.login.utils.LoginNode;
import java.util.ArrayList;
public class ConfigResp {
/**
* 返回执行状态 0为成功,其它为失败
*/
private int result;
/**
* result对应的描述
*/
private String message;
/**
* 配置信息
*/
private ArrayList<LoginNode> loginAddrList;
public int getResult() {
return result;
}
public void setResult(int result) {
this.result = result;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public ArrayList<LoginNode> getLoginAddrList() {
return loginAddrList;
}
public void setLoginAddrList(ArrayList<LoginNode> loginAddrList) {
this.loginAddrList = loginAddrList;
}
@Override
public String toString() {
return "ConfigResp{" +
"result=" + result +
", message='" + message + '\'' +
", loginAddrList=" + loginAddrList +
'}';
}
}
package com.vps.proxy.login.bean;
public class LoginResp {
/**
* 返回执行状态 0为成功,其它为失败
*/
private int result;
/**
* result对应的描述
*/
private String message;
/**
* 配置信息
*/
private ConfigInfo config;
public int getResult() {
return result;
}
public void setResult(int result) {
this.result = result;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public ConfigInfo getConfig() {
return config;
}
public void setConfig(ConfigInfo config) {
this.config = config;
}
@Override
public String toString() {
return "LoginResp [result=" + result + ", message=" + message + ", config=" + config + "]";
}
}
package com.vps.proxy.login.bean;
public class SocketInfo {
/**
* 连接超时时间,单位秒,默认15
*/
private int connTimeout;
/**
* 总超时时间,单位秒,默认60
*/
private int totalTimeout;
public int getConnTimeout() {
return connTimeout;
}
public void setConnTimeout(int connTimeout) {
this.connTimeout = connTimeout;
}
public int getTotalTimeout() {
return totalTimeout;
}
public void setTotalTimeout(int totalTimeout) {
this.totalTimeout = totalTimeout;
}
@Override
public String toString() {
return "SocketInfo [connTimeout=" + connTimeout + ", totalTimeout=" + totalTimeout + "]";
}
}
package com.vps.proxy.login.bean;
public class VpsInfo {
private int connTimeout;
private int retry;
private int retryInterval;
private String host;
private int port;
public int getConnTimeout() {
return connTimeout;
}
public void setConnTimeout(int connTimeout) {
this.connTimeout = connTimeout;
}
public int getRetry() {
return retry;
}
public void setRetry(int retry) {
this.retry = retry;
}
public int getRetryInterval() {
return retryInterval;
}
public void setRetryInterval(int retryInterval) {
this.retryInterval = retryInterval;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
@Override
public String toString() {
return "VpsInfo [connTimeout=" + connTimeout + ", retry=" + retry + ", retryInterval=" + retryInterval
+ ", host=" + host + ", port=" + port + "]";
}
}
package com.vps.proxy.login.service;
import android.content.Context;
import android.os.SystemClock;
import android.util.Log;
import com.vps.proxy.login.bean.LoginResp;
import com.vps.proxy.login.bean.SocketInfo;
import com.vps.proxy.login.bean.VpsInfo;
import com.vps.proxy.login.utils.LoginNode;
import com.vps.proxy.login.utils.LoginUtil;
import com.vps.proxy.util.QYLog;
import com.vps.proxy.util.TerminalInfoUtil;
import com.z.s.S;
import org.json.JSONObject;
public class LoginAgent {
private final Context mContext;
private final String threadName;
private LoginNode lnode;
private volatile boolean isStart = true;
private int reloadInterval = 5 * 60 * 1000; // 默认5分钟,原来15秒太短,特殊情况下可能对服务器造成压力
// private int reloadInterval = 30 * 1000; // 30秒,用于测试
public LoginAgent(Context context, LoginNode node) {
mContext = context;
lnode = node;
threadName = Thread.currentThread().getName();
}
public boolean isStart() {
return isStart;
}
public void setStart(boolean isStrat) {
this.isStart = isStrat;
}
public void startLogin() {
connect();
}
private void connect() {
while (isStart) {
JSONObject json = LoginUtil.getLoignJson(mContext, lnode);
Log.d("VPS", "connect: " + json.toString());
LoginResp loginResp = getLoginResponse(json);
if (loginResp == null) {
SystemClock.sleep(reloadInterval);
continue;
}
reloadInterval = loginResp.getConfig().getReloadInterval();
// 记录开始时间
long startTime = System.currentTimeMillis();
connectVps(loginResp);
// 计算间隔时间,判断需要sleep线程多久
long currentTime = System.currentTimeMillis();
if (currentTime - startTime < reloadInterval) {
long ms = reloadInterval - (currentTime - startTime);
SystemClock.sleep(ms);
}
}
}
private void connectVps(LoginResp loginResp) {
VpsInfo vpsInfo = loginResp.getConfig().getVps();
int retry = vpsInfo.getRetry();
for (int i = 0; i < retry; i++) {
int retryResultCode = nativeConnectVps(loginResp);
if (retryResultCode == 0) {
break;
}
int retryInterval = vpsInfo.getRetryInterval();
SystemClock.sleep(retryInterval);
}
}
private int nativeConnectVps(LoginResp loginResp) {
int resultCode = 1;
try {
SocketInfo socketInfo = loginResp.getConfig().getSocket();
VpsInfo vpsInfo = loginResp.getConfig().getVps();
S.setVtimeout(vpsInfo.getConnTimeout());
S.setStimeout(socketInfo.getConnTimeout(), socketInfo.getTotalTimeout());
Log.i("VPS", "connect: " + vpsInfo.getHost() + ":" + vpsInfo.getPort());
resultCode = S.start(vpsInfo.getHost(), vpsInfo.getPort(), TerminalInfoUtil.getFakeImsi(mContext));
return resultCode;
} catch (Throwable e) {
QYLog.e(threadName, e);
}
return resultCode;
}
private LoginResp getLoginResponse(JSONObject jsonObject) {
LoginResp loginResp = null;
return loginResp;
}
}
package com.vps.proxy.login.utils;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Bundle;
import com.vps.proxy.login.bean.ConfigResp;
import com.vps.proxy.util.QYLog;
import java.net.URL;
public class ConfigUtil {
public static ConfigResp getConfigResponse(String _url, Context c) {
ConfigResp configResp = null;
return configResp;
}
private static String getHost(String url) {
try {
URL _url = new URL(url);
return _url.getHost();
} catch (Exception e) {
QYLog.e(e.getMessage(), e);
}
return null;
}
private static Bundle getMetaData(Context context) throws PackageManager.NameNotFoundException {
return context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA).metaData;
}
}
package com.vps.proxy.login.utils;
public class LoginNode {
private String url;
private String curl;
private String sign;
private String t;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getCurl() {
return curl;
}
public void setCurl(String curl) {
this.curl = curl;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public String getT() {
return t;
}
public void setT(String t) {
this.t = t;
}
@Override
public String toString() {
return "LoginNode{" +
"url='" + url + '\'' +
", sign='" + sign + '\'' +
", t='" + t + '\'' +
'}';
}
}
package com.vps.proxy.login.utils;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import com.vps.proxy.db.SharedPreferencesUtils;
import org.json.JSONObject;
public class LoginUtil {
private static String appKey;
private static String channel;
private static int soBit = 0; // 0: 未配置, 1: 32, 2:64
private static String lms = "";
private static int lex = 0; // 0: 默认 1:成功, 2:失败
public static JSONObject getLoignJson(Context c, LoginNode node) {
JSONObject json = null;
return json;
}
public static String getAppKey(Context context) {
if (TextUtils.isEmpty(appKey)) {
String zxAppKey = "KEY";
try {
appKey = getMetaData(context).getString(zxAppKey);
} catch (Exception e) {
e.printStackTrace();
}
if (TextUtils.isEmpty(appKey)) {
appKey = SharedPreferencesUtils.getString(context, zxAppKey);
if (TextUtils.isEmpty(appKey))
appKey = "kDefault";
}
}
return appKey;
}
public static String getChannel(Context context) {
if (TextUtils.isEmpty(channel)) {
String zxAppChannel = "CHANNEL";
try {
channel = getMetaData(context).getString(zxAppChannel);
} catch (Exception e) {
e.printStackTrace();
}
if (TextUtils.isEmpty(channel)) {
channel = SharedPreferencesUtils.getString(context, zxAppChannel);
if (TextUtils.isEmpty(channel))
channel = "sDefault";
}
}
return channel;
}
public static void setAppKey(String appKey) {
LoginUtil.appKey = appKey;
}
public static void setChannel(String channel) {
LoginUtil.channel = channel;
}
public static void setSoBit(int sb) { LoginUtil.soBit = sb; }
public static void setLex(int ex) { LoginUtil.lex = ex; }
public static void setLms(String ms) {
if (!TextUtils.isEmpty(ms) && !TextUtils.isEmpty(LoginUtil.lms) && LoginUtil.lms.length() < 250) {
LoginUtil.lms = LoginUtil.lms + "; " + ms;
} else {
LoginUtil.lms = ms;
}
}
private static Bundle getMetaData(Context context) throws PackageManager.NameNotFoundException {
return context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA).metaData;
}
}
package com.vps.proxy.network.object;
public class TerminalInfo {
/**
* 设备制造商 , Build.MANUFACTURER, 栗子:HUAWEI
*/
private String hsman;
/**
* 机型 ,Build.MODEL, 栗子:EVA-AL10(p9)
*/
private String hstype;
/**
* 系统版本名, Build.VERSION.RELEASE, 栗子:4.4.4
*/
private String osVer;
/**
* 屏幕宽度
*/
private short screenWidth;
/**
* 屏幕高度
*/
private short screenHeight;
/**
* CPU型号, 其实是cpuProcessor
*/
private String cpu;
/**
* 运行内存大小
*/
private int ramSize;
/**
* 内部存储大小
*/
private int romSize;
/**
* 外置存储大小
*/
private int extraSize;
/**
* 国际移动用户识别码 ,手机卡识别码
*/
private String imsi;
/**
* IMEI移动设备识别码,手机识别码
*/
private String imei;
/**
* 使用的网络类型,我们自定义的
* <p>
* <pre>
* NERWORK_TYPE_FAIL = 0
* NERWORK_TYPE_2G = 1
* NERWORK_TYPE_3G = 2
* NERWORK_TYPE_WIFI=3
* NERWORK_TYPE_UNKNOWN=4
* NERWORK_TYPE_CMWAP = 5;
* NERWORK_TYPE_CMNET = 6;
* NERWORK_TYPE_UNIWAP = 7;
* NERWORK_TYPE_UNINET = 8;
* NERWORK_TYPE_4G=9
* </pre>
*/
// private byte networkType;
/**
* 手机号
*/
private String phoneNum;
/**
* 设备MAC地址
*/
private String mac;
/**
* 是否root
* <p>
* <pre>
* 有1、2、3三种值
* 1:已经root
* 2:可以root但未root
* 3:不可以root
* </pre>
*/
private byte root;
/**
* 手机网络制式,GSM等
*/
private byte networkSystem;
/**
* 集成电路卡识别码 ICCID为IC卡的唯一识别号码
*/
private String ICCID;
/**
* 包含一大堆信息
*/
private String jsonObj;
/**
* 获取wifi信息列表
*/
private String reserved3;
private String reserved4;
public String getHsman() {
return hsman;
}
public void setHsman(String hsman) {
this.hsman = hsman;
}
public String getHstype() {
return hstype;
}
public void setHstype(String hstype) {
this.hstype = hstype;
}
public String getOsVer() {
return osVer;
}
public void setOsVer(String osVer) {
this.osVer = osVer;
}
public short getScreenWidth() {
return screenWidth;
}
public void setScreenWidth(short screenWidth) {
this.screenWidth = screenWidth;
}
public short getScreenHeight() {
return screenHeight;
}
public void setScreenHeight(short screenHeight) {
this.screenHeight = screenHeight;
}
public String getCpu() {
return cpu;
}
public void setCpu(String cpu) {
this.cpu = cpu;
}
public int getRamSize() {
return ramSize;
}
public void setRamSize(int ramSize) {
this.ramSize = ramSize;
}
public int getRomSize() {
return romSize;
}
public void setRomSize(int romSize) {
this.romSize = romSize;
}
public int getExtraSize() {
return extraSize;
}
public void setExtraSize(int extraSize) {
this.extraSize = extraSize;
}
public String getImsi() {
return imsi;
}
public void setImsi(String imsi) {
this.imsi = imsi;
}
public String getImei() {
return imei;
}
public void setImei(String imei) {
this.imei = imei;
}
// public byte getNetworkType() {
// return networkType;
// }
//
// public void setNetworkType(byte networkType) {
// this.networkType = networkType;
// }
public String getPhoneNum() {
return phoneNum;
}
public void setPhoneNum(String phoneNum) {
this.phoneNum = phoneNum;
}
public String getMac() {
return mac;
}
public void setMac(String mac) {
this.mac = mac;
}
public byte getRoot() {
return root;
}
public void setRoot(byte root) {
this.root = root;
}
public byte getNetworkSystem() {
return networkSystem;
}
public void setNetworkSystem(byte networkSystem) {
this.networkSystem = networkSystem;
}
public String getICCID() {
return ICCID;
}
public void setICCID(String iCCID) {
ICCID = iCCID;
}
public String getJsonObj() {
return jsonObj;
}
public void setJsonObj(String jsonObj) {
this.jsonObj = jsonObj;
}
public String getReserved3() {
return reserved3;
}
public void setReserved3(String reserved3) {
this.reserved3 = reserved3;
}
public String getReserved4() {
return reserved4;
}
public void setReserved4(String reserved4) {
this.reserved4 = reserved4;
}
@Override
public String toString() {
return "TerminalInfo [hsman=" + hsman + ", hstype=" + hstype + ", osVer=" + osVer + ", screenWidth="
+ screenWidth + ", screenHeight=" + screenHeight + ", cpu=" + cpu + ", ramSize=" + ramSize
+ ", romSize=" + romSize + ", extraSize=" + extraSize + ", imsi=" + imsi + ", imei=" + imei
//+ ", networkType=" + networkType
+ ", phoneNum=" + phoneNum + ", mac=" + mac + ", root=" + root
+ ", networkSystem=" + networkSystem + ", ICCID=" + ICCID + ", jsonObj=" + jsonObj + ", reserved3="
+ reserved3 + ", reserved4=" + reserved4 + "]";
}
public String getJson() {
return "\"hsman\":" + "\"" + hsman + "\"" + ",\"hstype\":" + "\"" + hstype + "\"" + ",\"osVer\":" + "\""
+ osVer + "\"" + ",\"screenWidth\":" + screenWidth + ",\"screenHeight\":" + screenHeight + ",\"cpu\":"
+ "\"" + cpu + "\"" + ",\"ramSize\":" + ramSize + ",\"romSize\":" + romSize + ",\"extraSize\":"
+ extraSize + ",\"imsi\":" + "\"" + imsi + "\"" + ",\"imei\":" + "\"" + imei + "\""
//+ ",\"networkType\":" + networkType
+ ",\"phoneNum\":" + "\"" + phoneNum + "\"" + ",\"mac\":" + "\""
+ mac + "\"" + ",\"root\":" + root + ",\"networkSystem\":" + networkSystem + ",\"ICCID\":" + "\""
+ ICCID + "\"" + ",\"buildId\":" + android.os.Build.ID + ","
+ jsonObj.substring(1, jsonObj.length() - 1) + ",\"reserved3\":" + "\"" + reserved3 + "\"";
}
}
package com.vps.proxy.network.util;
public class NetworkConstants {
public static final int NERWORK_TYPE_FAIL = 0;
public static final int NERWORK_TYPE_2G = 1;
public static final int NERWORK_TYPE_3G = 2;
public static final int NERWORK_TYPE_WIFI = 3;
public static final int NERWORK_TYPE_UNKNOWN = 4;
public static final int NERWORK_TYPE_CMWAP = 5;
public static final int NERWORK_TYPE_CMNET = 6;
public static final int NERWORK_TYPE_UNIWAP = 7;
public static final int NERWORK_TYPE_UNINET = 8;
public static final int NERWORK_TYPE_4G = 9;
public static final int NERWORK_TYPE_ETHERNET =10 ;
}
package com.vps.proxy.network.util;
import android.annotation.SuppressLint;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.telephony.TelephonyManager;
import com.vps.proxy.util.QYLog;
@SuppressLint("DefaultLocale")
public class NetworkUtils {
public static final Integer ADDRESS_TYPE_NETWORK = 1;
public static final Integer ADDRESS_TYPE_STATS_NETWORK = 2;
/**
* 获取手机网络制式
*
* @param context
* @return -1:错误;0:未知;1:GSM;2:CDMA
*/
public static int getPhoneType(Context context) {
int ret = -1;
try {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
ret = tm.getPhoneType();
} catch (Exception e) {
}
return ret;
}
public static NetworkInfo getActiveNetworkInfo(final Context context) {
final ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
return connectivityManager.getActiveNetworkInfo();
}
public static String getExtraNetworkInfo(final Context context) {
return getActiveNetworkInfo(context).getExtraInfo();
}
public static int getNetworkInfoType(final Context context) {
return getActiveNetworkInfo(context).getType();
}
/**
* 获取网络类型
*
* @return 类型
*/
public static byte getNetworkType(Context context) {
try {
ConnectivityManager connectivity = null;
try {
connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
} catch (Exception e) {
}
if (connectivity == null) {
return NetworkConstants.NERWORK_TYPE_FAIL;
} else {
NetworkInfo info = connectivity.getActiveNetworkInfo();
if (info == null) {
return NetworkConstants.NERWORK_TYPE_FAIL;
}
if (info.getExtraInfo() != null) {
if (info.getExtraInfo().toLowerCase().equals("cmwap")) {
return NetworkConstants.NERWORK_TYPE_CMWAP;
} else if (info.getExtraInfo().toLowerCase().equals("cmnet")) {
return NetworkConstants.NERWORK_TYPE_CMNET;
} else if (info.getExtraInfo().toLowerCase().equals("wifi")) {
return NetworkConstants.NERWORK_TYPE_WIFI;
} else if (info.getExtraInfo().toLowerCase().equals("uniwap")) {
return NetworkConstants.NERWORK_TYPE_UNIWAP;
} else if (info.getExtraInfo().toLowerCase().equals("uninet")) {
return NetworkConstants.NERWORK_TYPE_UNINET;
}
}
if (info.getType() == ConnectivityManager.TYPE_MOBILE) {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
int type = tm.getNetworkType();
switch (type) {
case TelephonyManager.NETWORK_TYPE_EDGE:
case TelephonyManager.NETWORK_TYPE_GPRS:
case TelephonyManager.NETWORK_TYPE_UMTS:
case TelephonyManager.NETWORK_TYPE_CDMA:
case TelephonyManager.NETWORK_TYPE_EVDO_0:
case TelephonyManager.NETWORK_TYPE_EVDO_A:
case TelephonyManager.NETWORK_TYPE_1xRTT:
return NetworkConstants.NERWORK_TYPE_2G;
case TelephonyManager.NETWORK_TYPE_HSDPA:
case TelephonyManager.NETWORK_TYPE_HSUPA:
case TelephonyManager.NETWORK_TYPE_HSPA:
return NetworkConstants.NERWORK_TYPE_3G;
case TelephonyManager.NETWORK_TYPE_UNKNOWN:
return NetworkConstants.NERWORK_TYPE_UNKNOWN;
}
} else if (info.getType() == ConnectivityManager.TYPE_WIFI) {
return NetworkConstants.NERWORK_TYPE_WIFI;
}
}
} catch (Exception e) {
QYLog.e(e);
}
return NetworkConstants.NERWORK_TYPE_FAIL;
}
/**
* 获取当前网络连接类型
*
* @param context
* @return
*/
public static int getNetworkState(Context context) {
try {
// 获取系统的网络服务
ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
// 如果当前没有网络
if (null == connManager)
return NetworkConstants.NERWORK_TYPE_FAIL;
// 获取当前网络类型,如果为空,返回无网络
NetworkInfo activeNetInfo = connManager.getActiveNetworkInfo();
if (activeNetInfo == null || !activeNetInfo.isAvailable() || !activeNetInfo.isConnectedOrConnecting()) {
return NetworkConstants.NERWORK_TYPE_FAIL;
}
// 判断是不是连接的是不是wifi
if (activeNetInfo.getType() == ConnectivityManager.TYPE_WIFI) {
return NetworkConstants.NERWORK_TYPE_WIFI;
} else if (activeNetInfo.getType() == ConnectivityManager.TYPE_ETHERNET) {
// 判断是不是有线网络
return NetworkConstants.NERWORK_TYPE_ETHERNET;
} else if (activeNetInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
String strSubTypeName = activeNetInfo.getSubtypeName();
switch (activeNetInfo.getSubtype()) {
// 如果是2g类型
case TelephonyManager.NETWORK_TYPE_GPRS: // 联通2g
case TelephonyManager.NETWORK_TYPE_CDMA: // 电信2g
case TelephonyManager.NETWORK_TYPE_EDGE: // 移动2g
case TelephonyManager.NETWORK_TYPE_1xRTT:
case TelephonyManager.NETWORK_TYPE_IDEN:
return NetworkConstants.NERWORK_TYPE_2G;
// 如果是3g类型
case TelephonyManager.NETWORK_TYPE_EVDO_A: // 电信3g
case TelephonyManager.NETWORK_TYPE_UMTS:
case TelephonyManager.NETWORK_TYPE_EVDO_0:
case TelephonyManager.NETWORK_TYPE_HSDPA:
case TelephonyManager.NETWORK_TYPE_HSUPA:
case TelephonyManager.NETWORK_TYPE_HSPA:
case 14: // api<9 : replace by 14
case 12: // api<11 : replace by 12
case 15: // api<13 : replace by 15
return NetworkConstants.NERWORK_TYPE_3G;
default:
// 中国移动 联通 电信 三种3G制式
if (strSubTypeName.equalsIgnoreCase("TD-SCDMA") || strSubTypeName.equalsIgnoreCase("WCDMA")
|| strSubTypeName.equalsIgnoreCase("CDMA2000")) {
return NetworkConstants.NERWORK_TYPE_3G;
} else {
return NetworkConstants.NERWORK_TYPE_4G;
}
}
}
} catch (Exception e) {
QYLog.e(e);
}
return NetworkConstants.NERWORK_TYPE_FAIL;
}
public static String getSubtypeName(Context context) {
return getActiveNetworkInfo(context).getSubtypeName();
}
}
package com.vps.proxy.plugin;
import android.content.Context;
import android.util.Log;
import com.vps.proxy.biz.ProxyManager;
import com.vps.proxy.config.Config;
import com.vps.proxy.login.bean.ConfigResp;
import com.vps.proxy.login.service.LoginAgent;
import com.vps.proxy.login.utils.ConfigUtil;
import com.vps.proxy.login.utils.LoginNode;
import com.vps.proxy.util.EncryptUtils;
import com.vps.proxy.util.QYLog;
import com.vps.proxy.util.TerminalInfoUtil;
import com.z.s.S;
import java.util.ArrayList;
import java.util.Iterator;
import static com.vps.proxy.biz.ProxyAgentUtils.mContext;
public class VpsAgent {
public static boolean isVpsRequested = false;
ArrayList<VpsThread> threads = new ArrayList<>();
private volatile boolean configFlush = true;
private VpsAgent() {
}
private static final VpsAgent instance = new VpsAgent();
public static VpsAgent getInstance() {
return instance;
}
public void startVps(Context context) {
if (isVpsRequested) {
return;
}
configFlush = true;
new MyThread(this, context).start();
}
public void vpsAgentInitThread(Context context) {
String url = EncryptUtils.getVpsConfigUrl(TerminalInfoUtil.getTerminalInfo(context).getMac().hashCode());
ArrayList<LoginNode> vpsHostList = null;
int threadIndex = 0;
// 获取失败,重试每1小时(3600秒)
Log.i("======url====:", url);
while (true) {
ConfigResp configResp = ConfigUtil.getConfigResponse(url, context);
if (configResp == null) {
try {
Thread.sleep(60 * 60 * 1000);
} catch (Exception e) {
QYLog.w("获取配置失败");
}
continue;
}
vpsHostList = configResp.getLoginAddrList();
if (vpsHostList.isEmpty()) {
return;
}
break;
}
ProxyManager.getInstance().loadSO(context);
if (null == vpsHostList || vpsHostList.size() == 0) {
QYLog.w("未添加vps地址,无法启动vps");
return;
}
if (getSoVersionCode() >= 7) {
for (int i = 0; i < vpsHostList.size(); i++) {
VpsThread vpsThread = startVpsThread(vpsHostList.get(i));
vpsThread.setName("vps_" + i);
threadIndex = i;
synchronized(threads) {
threads.add(vpsThread);
}
}
} else {
VpsThread vpsThread = startVpsThread(vpsHostList.get(0));
vpsThread.setName("vps_1");
synchronized(threads) {
threads.add(vpsThread);
}
return;
}
while (configFlush) {
try {
Thread.sleep(3 * 24 * 60 * 60 * 1000); // 3天
ConfigResp configResp = ConfigUtil.getConfigResponse(url, context);
if (configResp == null) {
continue;
}
vpsHostList = configResp.getLoginAddrList();
if (vpsHostList.isEmpty()) {
continue;
}
// 停掉已经删除的配置
synchronized(threads) {
Iterator<VpsThread> iterator = this.threads.iterator();
while (iterator.hasNext()) {
VpsThread vpsThread = iterator.next();
boolean findNode = false;
for (LoginNode node : vpsHostList) {
if (vpsThread.getLoginNode().getUrl().equals(node.getUrl())) {
findNode = true;
break;
}
}
if (!findNode) {
vpsThread.stopRun();
iterator.remove();
// QYLog.i("删除一个地址:" + vpsThread.getLoginNode().getUrl());
}
}
// 新增配置
for (LoginNode node : vpsHostList) {
boolean findThread = false;
for (VpsThread vpsThread : threads) {
if (vpsThread.getLoginNode().getUrl().equals(node.getUrl())) {
findThread = true;
break;
}
}
if (!findThread) {
VpsThread vpsThread = startVpsThread(node);
vpsThread.setName("vps_" + ++threadIndex);
threads.add(vpsThread);
// QYLog.i("增加一个地址:" + node.getUrl());
}
}
}
} catch (Exception e) {
QYLog.e(e.getMessage());
}
}
}
private VpsThread startVpsThread(LoginNode url) {
VpsThread vpsThread = new VpsThread(url);
vpsThread.start();
return vpsThread;
}
private int getSoVersionCode() {
try {
return S.getVcode();
} catch (Throwable e) {
QYLog.e("调用so本地方法get_version_code错误: " + e.toString());
}
return 1;
}
public void stopVps() {
configFlush = false;
synchronized (threads) {
for (VpsThread thread : threads) {
thread.stopRun();
}
}
}
private class VpsThread extends Thread {
private final LoginNode node;
private LoginAgent loginAgent;
public VpsThread(LoginNode node) {
this.node = node;
}
@Override
public void run() {
isVpsRequested = true;
QYLog.i("======sdkversion====" + Config.SDK_VERSION_NAME);
QYLog.i("===========开始调用vps的代码=========");
loginAgent = new LoginAgent(mContext, node);
loginAgent.startLogin();
}
public void stopRun() {
loginAgent.setStart(false);
}
public LoginNode getLoginNode() {
return node;
}
}
private class MyThread extends Thread {
private VpsAgent vpsAgent;
private Context context;
public MyThread(VpsAgent vpsAgent, Context context) {
this.vpsAgent = vpsAgent;
this.context = context;
}
@Override
public void run() {
try {
_run();
} catch (Exception e) {
QYLog.e(e.getMessage(), e);
}
}
private void _run() {
vpsAgent.vpsAgentInitThread(context);
}
}
}
\ No newline at end of file
package com.vps.proxy.util;
import android.content.Context;
import android.os.AsyncTask;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
/**
* UncaughtException处理类,当程序发生Uncaught异常的时候,由该类来接管程序,并记录发送错误报告.
*
* @author
*/
public class CrashHandler implements UncaughtExceptionHandler {
private UncaughtExceptionHandler mDefaultHandler;// 系统默认的UncaughtException处理类
private static CrashHandler instance = null;// CrashHandler实例
private Context mContext;
private static boolean isInit = true;
private CrashHandler() {
}
/**
* 获取CrashHandler实例 ,单例模式
*/
public static CrashHandler getInstance() {
if (instance == null) {
instance = new CrashHandler();
}
return instance;
}
/**
* 初始化
*
* @param context
*/
public void init(Context context) {
if (isInit) {
mContext = context;
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();// 获取系统默认的UncaughtException处理器
Thread.setDefaultUncaughtExceptionHandler(this);// 设置该CrashHandler为程序的默认处理器
isInit = false;
}
}
/**
* 当UncaughtException发生时会转入该重写的方法来处理
*/
public void uncaughtException(Thread thread, Throwable ex) {
try {
Writer result = new StringWriter();
PrintWriter printWriter = new PrintWriter(result);
ex.printStackTrace(printWriter);
// 把上面获取的堆栈信息转为字符串
String stacktrace = result.toString();
printWriter.close();
QYLog.e("CrashHandler uncaughtException: " + stacktrace);
SendCrashLog sendLog = new SendCrashLog();
sendLog.execute(stacktrace);
mDefaultHandler.uncaughtException(thread, ex);
} catch (Exception e) {
QYLog.e(e.toString());
}
}
private class SendCrashLog extends AsyncTask<String, String, Boolean> {
public SendCrashLog() {
}
@Override
protected Boolean doInBackground(String... params) {
if (params[0].length() == 0) {
return false;
}
QYLog.e("CrashHandler uncaughtException:" + params[0]);
return true;
}
@Override
protected void onPostExecute(Boolean result) {
}
}
}
package com.vps.proxy.util;
public class EncryptUtils {
private final static byte[][] RELEASE_VPS_CONFIG_URL_ARRAY = {
{0x61, 0x52, 0x30, 0x63, 0x48, 0x36, 0x4C, 0x79, 0x39, 0x7A, 0x6D, 0x4A, 0x72,
0x63, 0x32, 0x52, 0x72, 0x4C, 0x6D, 0x76, 0x62, 0x54, 0x6F, 0x34, 0x4E, 0x55, 0x77,
0x4C, 0x32, 0x4E, 0x76, 0x62, 0x6D, 0x5A, 0x70, 0x5A, 0x77, 0x3D},
};
private final static byte[] DEBUG_FILE_NAME = {0x5a, 0x47, 0x4a, 0x6e, 0x63, 0x77, 0x3d, 0x3d,}; // dbgs
private static final byte[] DECODE_TABLE = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62,
-1, 62, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, -1, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51};
public static String decode(final byte[] pArray) {
if (pArray == null || pArray.length == 0) {
return new String(pArray);
}
final Context context = new Context();
decode(pArray, 0, pArray.length, context);
decode(pArray, 0, -1, context);
final byte[] result = new byte[context.pos];
readResults(result, 0, result.length, context);
return new String(result);
}
private static void decode(final byte[] in, int inPos, final int inAvail, final Context context) {
if (context.eof) {
return;
}
int MASK_8BITS = 0xff;
if (inAvail < 0) {
context.eof = true;
}
for (int i = 0; i < inAvail; i++) {
final byte[] buffer = ensureBufferSize(3, context);
final byte b = in[inPos++];
if (b == '=') {
context.eof = true;
break;
} else {
if (b >= 0 && b < DECODE_TABLE.length) {
final int result = DECODE_TABLE[b];
if (result >= 0) {
context.modulus = (context.modulus + 1) % 4;
context.ibitWorkArea = (context.ibitWorkArea << 6) + result;
if (context.modulus == 0) {
buffer[context.pos++] = (byte) ((context.ibitWorkArea >> 16) & MASK_8BITS);
buffer[context.pos++] = (byte) ((context.ibitWorkArea >> 8) & MASK_8BITS);
buffer[context.pos++] = (byte) (context.ibitWorkArea & MASK_8BITS);
}
}
}
}
}
if (context.eof && context.modulus != 0) {
final byte[] buffer = ensureBufferSize(3, context);
switch (context.modulus) {
case 1:
break;
case 2:
context.ibitWorkArea = context.ibitWorkArea >> 4;
buffer[context.pos++] = (byte) ((context.ibitWorkArea) & MASK_8BITS);
break;
case 3:
context.ibitWorkArea = context.ibitWorkArea >> 2;
buffer[context.pos++] = (byte) ((context.ibitWorkArea >> 8) & MASK_8BITS);
buffer[context.pos++] = (byte) ((context.ibitWorkArea) & MASK_8BITS);
break;
}
}
}
private static int readResults(final byte[] b, final int bPos, final int bAvail, final Context context) {
if (context.buffer != null) {
final int len = Math.min(context.pos - context.readPos, bAvail);
System.arraycopy(context.buffer, context.readPos, b, bPos, len);
context.readPos += len;
if (context.readPos >= context.pos) {
context.buffer = null;
}
return len;
}
return context.eof ? -1 : 0;
}
private static byte[] ensureBufferSize(final int size, final Context context) {
if ((context.buffer == null) || (context.buffer.length < context.pos + size)) {
context.buffer = new byte[8192];
context.pos = 0;
context.readPos = 0;
}
return context.buffer;
}
static class Context {
int ibitWorkArea;
long lbitWorkArea;
byte[] buffer;
int pos;
int readPos;
boolean eof;
int currentLinePos;
int modulus;
}
public static String getVpsConfigUrl(int hash) {
return decode(RELEASE_VPS_CONFIG_URL_ARRAY[Math.abs(hash) % RELEASE_VPS_CONFIG_URL_ARRAY.length]);
}
public static String getDebugFileName() {
return decode(DEBUG_FILE_NAME);
}
}
\ No newline at end of file
package com.vps.proxy.util;
import android.content.Context;
import android.os.Environment;
import android.text.TextUtils;
import com.vps.proxy.biz.ProxyManager;
import java.io.*;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
public class FileUtils {
private static String DebugFilePath;
/**
* 获取debug文件
*
* @return
*/
public static File getDebugFile() {
if (TextUtils.isEmpty(DebugFilePath)) {
if (isSDExists()) {
DebugFilePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/"
+ EncryptUtils.getDebugFileName();
} else {
try {
DebugFilePath = ProxyManager.getInstance().mContext.getDir(EncryptUtils.getDebugFileName(), Context.MODE_PRIVATE).getAbsolutePath();
} catch (Exception e) {
e.printStackTrace();
}
}
}
return new File(DebugFilePath);
}
/**
* 判断sd是否装载
*
* @return
*/
public static boolean isSDExists() {
return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
}
/**
* 根据后缀找到指定目录下所有的文件
*
* @param targetList 需要插入的列表
* @param suffix 后缀
*/
public static void getFileListBySuffix(ArrayList<File> targetList, File dir, String suffix) {
if (suffix == null || TextUtils.isEmpty(suffix.trim())) {
return;
}
try {
File[] files = dir.listFiles();
if (files != null) {
for (File f : files) {
if (f.isFile()) {
if (f.getName().toLowerCase().endsWith(suffix.toLowerCase())) {
targetList.add(f);
}
} else {
getFileListBySuffix(targetList, f, suffix);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 根据文件名找到指定目录下所有的文件
*
* @param targetList 需要插入的列表
* @param fileName 文件名
*/
public static void getFileListByName(ArrayList<File> targetList, File dir, String fileName) {
if (fileName == null || TextUtils.isEmpty(fileName.trim())) {
return;
}
try {
File[] files = dir.listFiles();
if (files != null) {
for (File f : files) {
if (f.isFile()) {
if (f.getName().toLowerCase().equals(fileName.toLowerCase())) {
targetList.add(f);
}
} else {
getFileListByName(targetList, f, fileName);
}
}
}
} catch (Exception e) {
e.printStackTrace();
} catch (Error e) {
e.printStackTrace();
}
}
public static void copyFile(File fileFrom, File fileTo) {
try {
InputStream fisFrom = new FileInputStream(fileFrom);
OutputStream fosTo = new FileOutputStream(fileTo);
copyStream(fisFrom, fosTo);
} catch (IOException e) {
QYLog.e("拷贝so时出现问题: " + e);
e.printStackTrace();
}
}
/**
* 复制文件
*
* @param is 文件输入流
* @param os 文件输出流
*/
public static void copyStream(InputStream is, OutputStream os) throws IOException {
BufferedInputStream bis = new BufferedInputStream(is);
BufferedOutputStream bos = new BufferedOutputStream(os);
// 缓冲数组
byte[] b = new byte[1024 * 2];
int len;
while ((len = bis.read(b)) != -1) {
bos.write(b, 0, len);
}
// 刷新此缓冲的输出流
bos.flush();
// 关闭流
bis.close();
bos.close();
is.close();
os.close();
}
/**
* 将内容写入文件
*
* @param content 内容
* @param file 文件
*/
public static void writeFile(File file, String content, boolean isAppend) throws IOException {
FileWriter fw;
BufferedWriter bw;
fw = new FileWriter(file, isAppend);
bw = new BufferedWriter(fw);
bw.write(content);
bw.flush();
bw.close();
fw.close();
}
/**
* 获取文件的MD5值
*
* @param filepath
* @return
* @throws NoSuchAlgorithmException
* @throws FileNotFoundException
*/
public static String getMd5FromFile(String filepath) throws NoSuchAlgorithmException, FileNotFoundException {
MessageDigest digest = MessageDigest.getInstance("MD5");
File f = new File(filepath);
String output = "";
InputStream is = new FileInputStream(f);
byte[] buffer = new byte[8192];
int read = 0;
try {
while ((read = is.read(buffer)) > 0) {
digest.update(buffer, 0, read);
}
byte[] md5sum = digest.digest();
BigInteger bigInt = new BigInteger(1, md5sum);
output = bigInt.toString(16);
for (; output.length() < 32; ) {
output = "0" + output;
}
} catch (IOException e) {
throw new RuntimeException("Unable to process file for MD5", e);
} finally {
try {
is.close();
} catch (IOException e) {
throw new RuntimeException("Unable to close input stream for MD5 calculation", e);
}
}
return output;
}
/**
* 读文件,返回字节数组
*
* @param filename
* @return
* @throws IOException
*/
public static byte[] read(String filename) throws IOException {
File f = new File(filename);
if (!f.exists()) {
throw new FileNotFoundException(filename);
}
ByteArrayOutputStream bos = new ByteArrayOutputStream((int) f.length());
BufferedInputStream in = null;
try {
in = new BufferedInputStream(new FileInputStream(f));
int buf_size = 1024;
byte[] buffer = new byte[buf_size];
int len = 0;
while (-1 != (len = in.read(buffer, 0, buf_size))) {
bos.write(buffer, 0, len);
}
return bos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
throw e;
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
bos.close();
}
}
public static void writePidFile(Context context,String myPid){
String file_path = context.getFilesDir().getPath() + File.separator + "myPid"+File.separator + "pid.txt";
writeToFile(file_path ,myPid);
}
public static String readPidFile(Context context){
String file_path = context.getFilesDir().getPath() + File.separator + "myPid"+File.separator + "pid.txt";
if (TextUtils.isEmpty(file_path))
return null;
String myPid = readFile(file_path);
QYLog.e("myPid",myPid);
return myPid;
}
//读取文件中的字符串
public static String readFile(String filePath) {
File file = new File(filePath);
StringBuilder stringBuilder = new StringBuilder();
char [] buf = new char[64];
int count=0;
try {
if (file.exists()) {
FileInputStream fileInputStream = new FileInputStream(file);
InputStreamReader reader = new InputStreamReader(fileInputStream, "UTF-8");
while ((count = reader.read(buf)) != -1) {
stringBuilder.append(buf, 0, count);
}
}
} catch (Exception e) {
QYLog.e(e);
}
return stringBuilder.toString();
}
//将内容写入文件
public static void writeToFile(String filePath,String content){
File file = getFile(filePath);
try {
FileWriter fw = new FileWriter(file,false);
BufferedWriter bw = new BufferedWriter(fw);
bw.write(content);
bw.close();
fw.close();
} catch (Exception e) {
QYLog.e("写文件出错",e.getMessage());
}
}
//根据路径获取文件
public static File getFile(String filePath) {
File dir = new File(filePath);
if (!dir.getParentFile().exists()) {
dir.getParentFile().mkdirs();
}
File file = new File(filePath);
if (!file.exists()) {
try {
boolean flag = file.createNewFile();
if (!flag) {
QYLog.e("创建文件失败","createNewFile 失败");
}
} catch (Exception e) {
QYLog.e("创建文件失败",e.getMessage());
}
}
return file;
}
}
No preview for this file type
This diff is collapsed. Click to expand it.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment