mirror of
https://github.com/springzfx/cgproxy.git
synced 2026-02-09 21:14:57 +08:00
clang format
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_BUILD_TYPE DEBUG)
|
||||
# set(CMAKE_BUILD_TYPE DEBUG)
|
||||
# set(CMAKE_BUILD_TYPE RELEASE)
|
||||
|
||||
project(cgproxy VERSION 4.0)
|
||||
|
||||
@@ -4,8 +4,8 @@ using namespace std;
|
||||
void print_usage() { fprintf(stdout, "usage: cgattach <pid> <cgroup>\n"); }
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int flag=setuid(0);
|
||||
if (flag!=0) {
|
||||
int flag = setuid(0);
|
||||
if (flag != 0) {
|
||||
perror("cgattach need root");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -19,5 +19,5 @@ int main(int argc, char *argv[]) {
|
||||
string pid = string(argv[1]);
|
||||
string cgroup_target = string(argv[2]);
|
||||
|
||||
CGPROXY::CGROUP::attach(pid,cgroup_target);
|
||||
CGPROXY::CGROUP::attach(pid, cgroup_target);
|
||||
}
|
||||
|
||||
@@ -1,31 +1,32 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "socket_client.hpp"
|
||||
#include <nlohmann/json.hpp>
|
||||
using json = nlohmann::json;
|
||||
using namespace CGPROXY;
|
||||
|
||||
bool attach2cgproxy(){
|
||||
pid_t pid=getpid();
|
||||
json j;
|
||||
j["type"] = MSG_TYPE_NOPROXY_PID;
|
||||
j["data"] = pid;
|
||||
int status;
|
||||
SOCKET::send(j.dump(), status);
|
||||
return status==0;
|
||||
bool attach2cgproxy() {
|
||||
pid_t pid = getpid();
|
||||
json j;
|
||||
j["type"] = MSG_TYPE_NOPROXY_PID;
|
||||
j["data"] = pid;
|
||||
int status;
|
||||
SOCKET::send(j.dump(), status);
|
||||
return status == 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
int shift=1;
|
||||
if (argc==1){
|
||||
error("usage: cgnoproxy [--debug] <CMD>\nexample: cgnoproxy curl -I https://www.google.com");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
processArgs(argc,argv,shift);
|
||||
int main(int argc, char *argv[]) {
|
||||
int shift = 1;
|
||||
if (argc == 1) {
|
||||
error("usage: cgnoproxy [--debug] <CMD>\nexample: cgnoproxy curl -I "
|
||||
"https://www.google.com");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
processArgs(argc, argv, shift);
|
||||
|
||||
if (!attach2cgproxy()){
|
||||
error("attach process failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (!attach2cgproxy()) {
|
||||
error("attach process failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
string s=join2str(argc-shift,argv+shift,' ');
|
||||
return system(s.c_str());
|
||||
string s = join2str(argc - shift, argv + shift, ' ');
|
||||
return system(s.c_str());
|
||||
}
|
||||
47
cgproxy.cpp
47
cgproxy.cpp
@@ -1,31 +1,32 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "socket_client.hpp"
|
||||
#include <nlohmann/json.hpp>
|
||||
using json = nlohmann::json;
|
||||
using namespace CGPROXY;
|
||||
|
||||
bool attach2cgproxy(){
|
||||
pid_t pid=getpid();
|
||||
json j;
|
||||
j["type"] = MSG_TYPE_PROXY_PID;
|
||||
j["data"] = pid;
|
||||
int status;
|
||||
SOCKET::send(j.dump(), status);
|
||||
return status==0;
|
||||
bool attach2cgproxy() {
|
||||
pid_t pid = getpid();
|
||||
json j;
|
||||
j["type"] = MSG_TYPE_PROXY_PID;
|
||||
j["data"] = pid;
|
||||
int status;
|
||||
SOCKET::send(j.dump(), status);
|
||||
return status == 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
int shift=1;
|
||||
if (argc==1){
|
||||
error("usage: cgproxy [--debug] <CMD>\nexample: cgroxy curl -I https://www.google.com");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
processArgs(argc,argv,shift);
|
||||
|
||||
if (!attach2cgproxy()){
|
||||
error("attach process failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
int main(int argc, char *argv[]) {
|
||||
int shift = 1;
|
||||
if (argc == 1) {
|
||||
error(
|
||||
"usage: cgproxy [--debug] <CMD>\nexample: cgroxy curl -I https://www.google.com");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
processArgs(argc, argv, shift);
|
||||
|
||||
string s=join2str(argc-shift,argv+shift,' ');
|
||||
return system(s.c_str());
|
||||
if (!attach2cgproxy()) {
|
||||
error("attach process failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
string s = join2str(argc - shift, argv + shift, ' ');
|
||||
return system(s.c_str());
|
||||
}
|
||||
96
cgproxyd.cpp
96
cgproxyd.cpp
@@ -1,17 +1,16 @@
|
||||
#include "cgroup_attach.hpp"
|
||||
#include "common.hpp"
|
||||
#include "config.hpp"
|
||||
#include "socket_server.hpp"
|
||||
#include <csignal>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <libconfig.h++>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <pthread.h>
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <csignal>
|
||||
#include "config.hpp"
|
||||
#include "cgroup_attach.hpp"
|
||||
|
||||
using namespace std;
|
||||
using json = nlohmann::json;
|
||||
@@ -19,66 +18,69 @@ using namespace CGPROXY::SOCKET;
|
||||
using namespace CGPROXY::CONFIG;
|
||||
using namespace CGPROXY::CGROUP;
|
||||
|
||||
namespace CGPROXY{
|
||||
namespace CGPROXY {
|
||||
|
||||
class cgproxyd{
|
||||
class cgproxyd {
|
||||
thread_arg arg_t;
|
||||
Config config;
|
||||
pthread_t socket_thread_id = -1;
|
||||
|
||||
static cgproxyd* instance;
|
||||
static int handle_msg_static(char* msg){
|
||||
static cgproxyd *instance;
|
||||
static int handle_msg_static(char *msg) {
|
||||
if (!instance) {
|
||||
error("no cgproxyd instance assigned");
|
||||
return ERROR;
|
||||
}
|
||||
return instance->handle_msg(msg);
|
||||
}
|
||||
static void signalHandler( int signum ){
|
||||
debug("Signal %d received.", &signum);
|
||||
if (!instance){ error("no cgproxyd instance assigned");}
|
||||
else { instance->stop(); }
|
||||
static void signalHandler(int signum) {
|
||||
debug("Signal %d received.", signum);
|
||||
if (!instance) {
|
||||
error("no cgproxyd instance assigned");
|
||||
} else {
|
||||
instance->stop();
|
||||
}
|
||||
exit(signum);
|
||||
}
|
||||
|
||||
int handle_msg(char *msg) {
|
||||
debug("received msg: %s", msg);
|
||||
json j;
|
||||
try{ j = json::parse(msg); }catch(exception& e){debug("msg paser error");return MSG_ERROR;}
|
||||
try {
|
||||
j = json::parse(msg);
|
||||
} catch (exception &e) {
|
||||
debug("msg paser error");
|
||||
return MSG_ERROR;
|
||||
}
|
||||
|
||||
int type, status;
|
||||
int pid, cgroup_target;
|
||||
try {
|
||||
type = j.at("type").get<int>();
|
||||
switch (type)
|
||||
{
|
||||
switch (type) {
|
||||
case MSG_TYPE_JSON:
|
||||
status=config.loadFromJson(j.at("data"));
|
||||
if (status==SUCCESS) status=applyConfig(&config);
|
||||
status = config.loadFromJson(j.at("data"));
|
||||
if (status == SUCCESS) status = applyConfig(&config);
|
||||
return status;
|
||||
break;
|
||||
case MSG_TYPE_CONFIG_PATH:
|
||||
status=config.loadFromFile(j.at("data").get<string>());
|
||||
if (status==SUCCESS) status=applyConfig(&config);
|
||||
status = config.loadFromFile(j.at("data").get<string>());
|
||||
if (status == SUCCESS) status = applyConfig(&config);
|
||||
return status;
|
||||
break;
|
||||
case MSG_TYPE_PROXY_PID:
|
||||
pid=j.at("data").get<int>();
|
||||
status=attach(pid, config.cgroup_proxy_preserved);
|
||||
pid = j.at("data").get<int>();
|
||||
status = attach(pid, config.cgroup_proxy_preserved);
|
||||
return status;
|
||||
break;
|
||||
case MSG_TYPE_NOPROXY_PID:
|
||||
pid=j.at("data").get<int>();
|
||||
status=attach(pid, config.cgroup_noproxy_preserved);
|
||||
pid = j.at("data").get<int>();
|
||||
status = attach(pid, config.cgroup_noproxy_preserved);
|
||||
return status;
|
||||
break;
|
||||
default:
|
||||
return MSG_ERROR;
|
||||
break;
|
||||
default: return MSG_ERROR; break;
|
||||
};
|
||||
} catch (out_of_range &e) {
|
||||
return MSG_ERROR;
|
||||
} catch (exception &e){
|
||||
} catch (out_of_range &e) { return MSG_ERROR; } catch (exception &e) {
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
@@ -86,25 +88,21 @@ class cgproxyd{
|
||||
pthread_t startSocketListeningThread() {
|
||||
arg_t.handle_msg = &handle_msg_static;
|
||||
pthread_t thread_id;
|
||||
int status =
|
||||
pthread_create(&thread_id, NULL, &SocketServer::startThread, &arg_t);
|
||||
if (status != 0)
|
||||
error("socket thread create failed");
|
||||
int status = pthread_create(&thread_id, NULL, &SocketServer::startThread, &arg_t);
|
||||
if (status != 0) error("socket thread create failed");
|
||||
return thread_id;
|
||||
}
|
||||
|
||||
void assignStaticInstance(){
|
||||
instance=this;
|
||||
}
|
||||
void assignStaticInstance() { instance = this; }
|
||||
|
||||
public:
|
||||
int start(int argc, char* argv[]) {
|
||||
public:
|
||||
int start(int argc, char *argv[]) {
|
||||
signal(SIGINT, &signalHandler);
|
||||
signal(SIGTERM,&signalHandler);
|
||||
signal(SIGHUP,&signalHandler);
|
||||
signal(SIGTERM, &signalHandler);
|
||||
signal(SIGHUP, &signalHandler);
|
||||
|
||||
int shift=1;
|
||||
processArgs(argc,argv,shift);
|
||||
int shift = 1;
|
||||
processArgs(argc, argv, shift);
|
||||
|
||||
config.loadFromFile(DEFAULT_CONFIG_FILE);
|
||||
applyConfig(&config);
|
||||
@@ -121,20 +119,18 @@ class cgproxyd{
|
||||
// no need to track running status
|
||||
return 0;
|
||||
}
|
||||
void stop(){
|
||||
void stop() {
|
||||
debug("stopping");
|
||||
system(TPROXY_IPTABLS_CLEAN);
|
||||
}
|
||||
~cgproxyd(){
|
||||
stop();
|
||||
}
|
||||
~cgproxyd() { stop(); }
|
||||
};
|
||||
|
||||
cgproxyd* cgproxyd::instance=NULL;
|
||||
cgproxyd *cgproxyd::instance = NULL;
|
||||
|
||||
}
|
||||
} // namespace CGPROXY
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
int main(int argc, char *argv[]) {
|
||||
CGPROXY::cgproxyd d;
|
||||
return d.start(argc,argv);
|
||||
return d.start(argc, argv);
|
||||
}
|
||||
@@ -1,66 +1,63 @@
|
||||
#ifndef CGPROUP_ATTACH_H
|
||||
#define CGPROUP_ATTACH_H
|
||||
|
||||
#include "common.hpp"
|
||||
#include <errno.h>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <regex>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include "common.hpp"
|
||||
using namespace std;
|
||||
|
||||
namespace CGPROXY::CGROUP{
|
||||
namespace CGPROXY::CGROUP {
|
||||
|
||||
bool exist(string path) {
|
||||
struct stat st;
|
||||
if (stat(path.c_str(), &st) != -1) {
|
||||
return S_ISDIR(st.st_mode);
|
||||
}
|
||||
if (stat(path.c_str(), &st) != -1) { return S_ISDIR(st.st_mode); }
|
||||
return false;
|
||||
}
|
||||
|
||||
bool validate(string pid, string cgroup) {
|
||||
bool pid_v = validPid(pid);
|
||||
bool cg_v = validCgroup(cgroup);
|
||||
if (pid_v && cg_v)
|
||||
return true;
|
||||
|
||||
if (pid_v && cg_v) return true;
|
||||
|
||||
error("attach paramater validate error");
|
||||
return_error
|
||||
}
|
||||
|
||||
string get_cgroup2_mount_point(int &status){
|
||||
char cgroup2_mount_point[100]="";
|
||||
FILE* fp = popen("findmnt -t cgroup2 -n -o TARGET", "r");
|
||||
int count=fscanf(fp,"%s",&cgroup2_mount_point);
|
||||
string get_cgroup2_mount_point(int &status) {
|
||||
char cgroup2_mount_point[100] = "";
|
||||
FILE *fp = popen("findmnt -t cgroup2 -n -o TARGET", "r");
|
||||
int count = fscanf(fp, "%s", &cgroup2_mount_point);
|
||||
fclose(fp);
|
||||
if (count=0){
|
||||
if (count = 0) {
|
||||
error("cgroup2 not supported");
|
||||
status=-1;
|
||||
status = -1;
|
||||
return NULL;
|
||||
}
|
||||
status=0;
|
||||
status = 0;
|
||||
return cgroup2_mount_point;
|
||||
}
|
||||
|
||||
int attach(const string pid, const string cgroup_target) {
|
||||
if (getuid()!=0) {
|
||||
if (getuid() != 0) {
|
||||
error("need root to attach cgroup");
|
||||
return_error
|
||||
}
|
||||
|
||||
debug("attaching %s to %s",pid.c_str(),cgroup_target.c_str());
|
||||
|
||||
debug("attaching %s to %s", pid.c_str(), cgroup_target.c_str());
|
||||
|
||||
int status;
|
||||
if (!validate(pid, cgroup_target)) return_error
|
||||
string cgroup_mount_point = get_cgroup2_mount_point(status);
|
||||
if (status!=0) return_error
|
||||
string cgroup_target_path = cgroup_mount_point + cgroup_target;
|
||||
if (!validate(pid, cgroup_target))
|
||||
return_error string cgroup_mount_point = get_cgroup2_mount_point(status);
|
||||
if (status != 0)
|
||||
return_error string cgroup_target_path = cgroup_mount_point + cgroup_target;
|
||||
string cgroup_target_procs = cgroup_target_path + "/cgroup.procs";
|
||||
|
||||
// check if exist, we will create it if not exist
|
||||
@@ -87,17 +84,17 @@ int attach(const string pid, const string cgroup_target) {
|
||||
|
||||
// maybe there some write error, for example process pid may not exist
|
||||
if (!procs) {
|
||||
error("write %s to %s failed, maybe process %s not exist",
|
||||
pid.c_str(), cgroup_target_procs.c_str(), pid.c_str());
|
||||
error("write %s to %s failed, maybe process %s not exist", pid.c_str(),
|
||||
cgroup_target_procs.c_str(), pid.c_str());
|
||||
return_error
|
||||
}
|
||||
return_success
|
||||
}
|
||||
|
||||
int attach(const int pid, const string cgroup_target){
|
||||
int attach(const int pid, const string cgroup_target) {
|
||||
return attach(to_str(pid), cgroup_target);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace CGPROXY::CGROUP
|
||||
|
||||
#endif
|
||||
84
common.hpp
84
common.hpp
@@ -27,39 +27,38 @@
|
||||
#define CGROUP_ERROR 6
|
||||
#define FILE_ERROR 7
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <regex>
|
||||
using namespace std;
|
||||
|
||||
static bool enable_debug=false;
|
||||
static bool print_help=false;
|
||||
static bool enable_debug = false;
|
||||
static bool print_help = false;
|
||||
|
||||
#define error(...) {fprintf(stderr, __VA_ARGS__);fprintf(stderr, "\n");}
|
||||
#define debug(...) if (enable_debug) {fprintf(stdout, __VA_ARGS__);fprintf(stdout, "\n");}
|
||||
#define error(...) \
|
||||
{ \
|
||||
fprintf(stderr, __VA_ARGS__); \
|
||||
fprintf(stderr, "\n"); \
|
||||
}
|
||||
#define debug(...) \
|
||||
if (enable_debug) { \
|
||||
fprintf(stdout, __VA_ARGS__); \
|
||||
fprintf(stdout, "\n"); \
|
||||
}
|
||||
#define return_error return -1;
|
||||
#define return_success return 0;
|
||||
|
||||
|
||||
void processArgs(const int argc, char *argv[], int &shift){
|
||||
for (int i=1;i<argc;i++){
|
||||
if (strcmp(argv[i], "--debug")==0){
|
||||
enable_debug=true;
|
||||
}
|
||||
if (strcmp(argv[i], "--help")==0){
|
||||
print_help=true;
|
||||
}
|
||||
if (argv[i][0]!='-') {
|
||||
break;
|
||||
}
|
||||
shift+=1;
|
||||
}
|
||||
void processArgs(const int argc, char *argv[], int &shift) {
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--debug") == 0) { enable_debug = true; }
|
||||
if (strcmp(argv[i], "--help") == 0) { print_help = true; }
|
||||
if (argv[i][0] != '-') { break; }
|
||||
shift += 1;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
string to_str(T... args) {
|
||||
template <typename... T> string to_str(T... args) {
|
||||
stringstream ss;
|
||||
ss.clear();
|
||||
ss << std::boolalpha;
|
||||
@@ -67,41 +66,34 @@ string to_str(T... args) {
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
string join2str(const vector<string> t, const char delm=' '){
|
||||
string s;
|
||||
for (const auto &e : t)
|
||||
e!=*(t.end()-1)?s+=e+delm:s+=e;
|
||||
return s;
|
||||
string join2str(const vector<string> t, const char delm = ' ') {
|
||||
string s;
|
||||
for (const auto &e : t) e != *(t.end() - 1) ? s += e + delm : s += e;
|
||||
return s;
|
||||
}
|
||||
|
||||
string join2str(const int argc,char** argv, const char delm=' '){
|
||||
string s;
|
||||
for (int i=0;i<argc;i++){
|
||||
s+=argv[i];
|
||||
if (i!=argc-1) s+=delm;
|
||||
}
|
||||
return s;
|
||||
string join2str(const int argc, char **argv, const char delm = ' ') {
|
||||
string s;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
s += argv[i];
|
||||
if (i != argc - 1) s += delm;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
bool validCgroup(const string cgroup){
|
||||
bool validCgroup(const string cgroup) {
|
||||
return regex_match(cgroup, regex("^/[a-zA-Z0-9\\-_./@]*$"));
|
||||
}
|
||||
|
||||
bool validCgroup(const vector<string> cgroup){
|
||||
for (auto &e:cgroup){
|
||||
if (!regex_match(e, regex("^/[a-zA-Z0-9\\-_./@]*$"))){
|
||||
return false;
|
||||
}
|
||||
bool validCgroup(const vector<string> cgroup) {
|
||||
for (auto &e : cgroup) {
|
||||
if (!regex_match(e, regex("^/[a-zA-Z0-9\\-_./@]*$"))) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validPid(const string pid){
|
||||
return regex_match(pid, regex("^[0-9]+$"));
|
||||
}
|
||||
bool validPid(const string pid) { return regex_match(pid, regex("^[0-9]+$")); }
|
||||
|
||||
bool validPort(const int port){
|
||||
return port>0;
|
||||
}
|
||||
bool validPort(const int port) { return port > 0; }
|
||||
|
||||
#endif
|
||||
130
config.hpp
130
config.hpp
@@ -1,28 +1,27 @@
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
#include "common.hpp"
|
||||
#include "socket_server.hpp"
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <pthread.h>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <iomanip>
|
||||
using namespace std;
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace CGPROXY::CONFIG{
|
||||
namespace CGPROXY::CONFIG {
|
||||
|
||||
struct Config {
|
||||
public:
|
||||
const string cgroup_proxy_preserved=CGROUP_PROXY_PRESVERED;
|
||||
const string cgroup_noproxy_preserved=CGROUP_NOPROXY_PRESVERED;
|
||||
private:
|
||||
public:
|
||||
const string cgroup_proxy_preserved = CGROUP_PROXY_PRESVERED;
|
||||
const string cgroup_noproxy_preserved = CGROUP_NOPROXY_PRESVERED;
|
||||
|
||||
private:
|
||||
vector<string> cgroup_proxy;
|
||||
vector<string> cgroup_noproxy;
|
||||
bool enable_gateway = false;
|
||||
@@ -36,7 +35,7 @@ struct Config {
|
||||
public:
|
||||
void toEnv() {
|
||||
mergeReserved();
|
||||
setenv("cgroup_proxy", join2str(cgroup_proxy,':').c_str(), 1);
|
||||
setenv("cgroup_proxy", join2str(cgroup_proxy, ':').c_str(), 1);
|
||||
setenv("cgroup_noproxy", join2str(cgroup_noproxy, ':').c_str(), 1);
|
||||
setenv("enable_gateway", to_str(enable_gateway).c_str(), 1);
|
||||
setenv("port", to_str(port).c_str(), 1);
|
||||
@@ -47,48 +46,60 @@ public:
|
||||
setenv("enable_ipv6", to_str(enable_ipv6).c_str(), 1);
|
||||
}
|
||||
|
||||
int saveToFile(const string f){
|
||||
ofstream o(f);
|
||||
if (!o.is_open()) return FILE_ERROR;
|
||||
json j=toJson();
|
||||
o << setw(4) << j << endl;
|
||||
o.close();
|
||||
return 0;
|
||||
int saveToFile(const string f) {
|
||||
ofstream o(f);
|
||||
if (!o.is_open()) return FILE_ERROR;
|
||||
json j = toJson();
|
||||
o << setw(4) << j << endl;
|
||||
o.close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
json toJson(){
|
||||
json j;
|
||||
#define add2json(v) j[#v]=v;
|
||||
add2json(cgroup_proxy);
|
||||
add2json(cgroup_noproxy);
|
||||
add2json(enable_gateway);
|
||||
add2json(port);
|
||||
add2json(enable_dns);
|
||||
add2json(enable_tcp);
|
||||
add2json(enable_udp);
|
||||
add2json(enable_ipv4);
|
||||
add2json(enable_ipv6);
|
||||
#undef add2json
|
||||
return j;
|
||||
#define add2json(v) j[#v] = v;
|
||||
json toJson() {
|
||||
json j;
|
||||
add2json(cgroup_proxy);
|
||||
add2json(cgroup_noproxy);
|
||||
add2json(enable_gateway);
|
||||
add2json(port);
|
||||
add2json(enable_dns);
|
||||
add2json(enable_tcp);
|
||||
add2json(enable_udp);
|
||||
add2json(enable_ipv4);
|
||||
add2json(enable_ipv6);
|
||||
return j;
|
||||
}
|
||||
#undef add2json
|
||||
|
||||
int loadFromFile(const string f) {
|
||||
debug("loading config: %s", f.c_str());
|
||||
ifstream ifs(f);
|
||||
if (ifs.is_open()){
|
||||
if (ifs.is_open()) {
|
||||
json j;
|
||||
try { ifs >> j; }catch (exception& e){error("parse error: %s", f.c_str());ifs.close();return PARSE_ERROR;}
|
||||
try {
|
||||
ifs >> j;
|
||||
} catch (exception &e) {
|
||||
error("parse error: %s", f.c_str());
|
||||
ifs.close();
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
ifs.close();
|
||||
return loadFromJson(j);
|
||||
}else{
|
||||
error("open failed: %s",f.c_str());
|
||||
} else {
|
||||
error("open failed: %s", f.c_str());
|
||||
return FILE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
#define tryassign(v) \
|
||||
try { \
|
||||
j.at(#v).get_to(v); \
|
||||
} catch (exception & e) {}
|
||||
int loadFromJson(const json &j) {
|
||||
if (!validateJson(j)) {error("json validate fail"); return PARAM_ERROR;}
|
||||
#define tryassign(v) try{j.at(#v).get_to(v);}catch(exception &e){}
|
||||
if (!validateJson(j)) {
|
||||
error("json validate fail");
|
||||
return PARAM_ERROR;
|
||||
}
|
||||
tryassign(cgroup_proxy);
|
||||
tryassign(cgroup_noproxy);
|
||||
tryassign(enable_gateway);
|
||||
@@ -98,35 +109,36 @@ public:
|
||||
tryassign(enable_udp);
|
||||
tryassign(enable_ipv4);
|
||||
tryassign(enable_ipv6);
|
||||
#undef assign
|
||||
return 0;
|
||||
}
|
||||
#undef assign
|
||||
|
||||
void mergeReserved(){
|
||||
#define merge(v) { \
|
||||
v.erase(std::remove(v.begin(), v.end(), v ## _preserved), v.end()); \
|
||||
v.insert(v.begin(), v ## _preserved); \
|
||||
}
|
||||
#define merge(v) \
|
||||
{ \
|
||||
v.erase(std::remove(v.begin(), v.end(), v##_preserved), v.end()); \
|
||||
v.insert(v.begin(), v##_preserved); \
|
||||
}
|
||||
void mergeReserved() {
|
||||
merge(cgroup_proxy);
|
||||
merge(cgroup_noproxy);
|
||||
#undef merge
|
||||
|
||||
}
|
||||
#undef merge
|
||||
|
||||
bool validateJson(const json &j){
|
||||
bool status=true;
|
||||
const set<string> boolset={"enable_gateway","enable_dns","enable_tcp","enable_udp","enable_ipv4","enable_ipv6"};
|
||||
for (auto& [key, value] : j.items()) {
|
||||
if (key=="cgroup_proxy"||key=="cgroup_noproxy"){
|
||||
if (value.is_string()&&!validCgroup((string)value)) status=false;
|
||||
bool validateJson(const json &j) {
|
||||
bool status = true;
|
||||
const set<string> boolset = {"enable_gateway", "enable_dns", "enable_tcp",
|
||||
"enable_udp", "enable_ipv4", "enable_ipv6"};
|
||||
for (auto &[key, value] : j.items()) {
|
||||
if (key == "cgroup_proxy" || key == "cgroup_noproxy") {
|
||||
if (value.is_string() && !validCgroup((string)value)) status = false;
|
||||
// TODO what if vector<int> etc.
|
||||
if (value.is_array()&&!validCgroup((vector<string>)value)) status=false;
|
||||
if (!value.is_string()&&!value.is_array()) status=false;
|
||||
}else if (key=="port"){
|
||||
if (!validPort(value)) status=false;
|
||||
}else if (boolset.find(key)!=boolset.end()){
|
||||
if (!value.is_boolean()) status=false;
|
||||
}else{
|
||||
if (value.is_array() && !validCgroup((vector<string>)value)) status = false;
|
||||
if (!value.is_string() && !value.is_array()) status = false;
|
||||
} else if (key == "port") {
|
||||
if (!validPort(value)) status = false;
|
||||
} else if (boolset.find(key) != boolset.end()) {
|
||||
if (!value.is_boolean()) status = false;
|
||||
} else {
|
||||
error("unknown key: %s", key.c_str());
|
||||
return false;
|
||||
}
|
||||
@@ -139,5 +151,5 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace CGPROXY::CONFIG
|
||||
#endif
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef SOCKET_CLIENT_H
|
||||
#define SOCKET_CLIENT_H
|
||||
|
||||
#include "common.hpp"
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -9,18 +10,17 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
#include "common.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace CGPROXY::SOCKET{
|
||||
namespace CGPROXY::SOCKET {
|
||||
|
||||
#define return_if_error(flag, msg) \
|
||||
if (flag == -1) { \
|
||||
perror(msg); \
|
||||
status = CONN_ERROR; \
|
||||
close(sfd); \
|
||||
return; \
|
||||
#define return_if_error(flag, msg) \
|
||||
if (flag == -1) { \
|
||||
perror(msg); \
|
||||
status = CONN_ERROR; \
|
||||
close(sfd); \
|
||||
return; \
|
||||
}
|
||||
|
||||
void send(const char *msg, int &status) {
|
||||
@@ -35,8 +35,7 @@ void send(const char *msg, int &status) {
|
||||
unix_socket.sun_family = AF_UNIX;
|
||||
strncpy(unix_socket.sun_path, SOCKET_PATH, sizeof(unix_socket.sun_path) - 1);
|
||||
|
||||
flag =
|
||||
connect(sfd, (struct sockaddr *)&unix_socket, sizeof(struct sockaddr_un));
|
||||
flag = connect(sfd, (struct sockaddr *)&unix_socket, sizeof(struct sockaddr_un));
|
||||
return_if_error(flag, "connect");
|
||||
|
||||
int msg_len = strlen(msg);
|
||||
@@ -60,5 +59,5 @@ void send(const string msg, int &status) {
|
||||
debug("return status: %d", status);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace CGPROXY::SOCKET
|
||||
#endif
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef SOCKET_SERVER_H
|
||||
#define SOCKET_SERVER_H
|
||||
|
||||
#include "common.hpp"
|
||||
#include <filesystem>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <signal.h>
|
||||
@@ -8,21 +10,19 @@
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <filesystem>
|
||||
#include "common.hpp"
|
||||
using namespace std;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace CGPROXY::SOCKET{
|
||||
namespace CGPROXY::SOCKET {
|
||||
|
||||
#define continue_if_error(flag, msg) \
|
||||
if (flag == -1) { \
|
||||
perror(msg); \
|
||||
continue; \
|
||||
#define continue_if_error(flag, msg) \
|
||||
if (flag == -1) { \
|
||||
perror(msg); \
|
||||
continue; \
|
||||
}
|
||||
|
||||
struct thread_arg {
|
||||
@@ -38,19 +38,18 @@ public:
|
||||
debug("starting socket listening");
|
||||
sfd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
|
||||
if (fs::exists(SOCKET_PATH)&&unlink(SOCKET_PATH)==-1){
|
||||
error("%s exist, and can't unlink",SOCKET_PATH);
|
||||
if (fs::exists(SOCKET_PATH) && unlink(SOCKET_PATH) == -1) {
|
||||
error("%s exist, and can't unlink", SOCKET_PATH);
|
||||
return;
|
||||
}
|
||||
memset(&unix_socket, '\0', sizeof(struct sockaddr_un));
|
||||
unix_socket.sun_family = AF_UNIX;
|
||||
strncpy(unix_socket.sun_path, SOCKET_PATH,
|
||||
sizeof(unix_socket.sun_path) - 1);
|
||||
strncpy(unix_socket.sun_path, SOCKET_PATH, sizeof(unix_socket.sun_path) - 1);
|
||||
|
||||
bind(sfd, (struct sockaddr *)&unix_socket, sizeof(struct sockaddr_un));
|
||||
|
||||
listen(sfd, LISTEN_BACKLOG);
|
||||
chmod(SOCKET_PATH,S_IRWXU|S_IRWXG|S_IRWXO);
|
||||
chmod(SOCKET_PATH, S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
|
||||
while (true) {
|
||||
close(cfd);
|
||||
@@ -66,7 +65,7 @@ public:
|
||||
char msg[msg_len];
|
||||
flag = read(cfd, msg, msg_len * sizeof(char));
|
||||
continue_if_error(flag, "read msg");
|
||||
msg[msg_len]='\0';
|
||||
msg[msg_len] = '\0';
|
||||
// handle msg
|
||||
int status = callback(msg);
|
||||
// send back flag
|
||||
@@ -89,6 +88,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace CGPROXY::SOCKET
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user