3proxy/src/plugins/TrafficPlugin/TrafficPlugin.c

316 lines
9.9 KiB
C

/*
3proxy Traffic correct plugin v0.1 beta
Íàïèñàë Maslov Michael aka Flexx(rus)
Ôîðìóëà ðàñ÷¸òà òðàôôèêà ïî ðàçìåðó ïàêåòà by 3APA3A
email: flexx_rus@mail.ru
ICQ: 299132764
http://3proxy.ru/
Êàê ðàáîòàåò íå çíàþ (ìíîãîå çàâèñèò îò âàøèõ íàñòðîåê). Íèêàêèõ ãàðàíòèé.
Ñ ïëóãèíîì ìîæåòå äåëàòü âñ¸, ÷òî çàõî÷åòñÿ.
Äîæåí ðàñïðîñòðîíÿòüñÿ òîëüêî ñ èñõîäíûìè êîäàìè èëè âìåñòå ñ 3proxy.
Óäàëÿòü äàííûé Copyright çàïðåùåíî.
*/
#include "../../structures.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
int DBGLEVEL = 0;
int already_loaded = 0;
typedef int (* handler)(int argc, unsigned char ** argv);
struct extparam * conf;
struct commands * commandhandlers;
struct pluginlink * pl;
typedef enum {
MULTIPLAY, /* ìåòîä êîððåêöèè óìíîæåíèåì íà êîôôèöèåíò */
IPCORRECT, /* ìåòîä êîððåêöèè ñ ó÷¸òîì ðàçìåðà ïàêåòà */
} TRAFCORRECT_TYPE;
typedef enum {
UDP,
TCP
} CONN_TYPE;
struct trafcorrect {
struct trafcorrect * next;
TRAFCORRECT_TYPE type;
int port;
PROXYSERVICE p_service;
double coeff;
CONN_TYPE con_type;
int psize;
};
struct trafcorrect * firsttrafcorrect = NULL;
static void addtrafcorrect(struct trafcorrect * tc) {
struct trafcorrect * starttrafcorrect;
if (!firsttrafcorrect) {
firsttrafcorrect = tc;
return;
}
starttrafcorrect = firsttrafcorrect;
for ( ; starttrafcorrect->next ; starttrafcorrect = starttrafcorrect->next);
starttrafcorrect->next = tc;
}
static void killtrafcorrect() {
struct trafcorrect * p = firsttrafcorrect;
struct trafcorrect * d;
if (!firsttrafcorrect) return;
firsttrafcorrect = NULL;
while (p) {
d = p;
p = p->next;
free(d);
}
}
struct commands trafcorrect_handler;
int h_trafcorrect(int argc, unsigned char ** argv) {
if (argc < 2) {
if(DBGLEVEL == 1)fprintf(stdout, "See documentation of traffic correct plugin.\n");
return 1;
}
/* ðåæèì óìíîæåíèÿ òðàôôèêà íà êîýôôèöèåíò */
if (!strcmp((char *)argv[1], "m")) {
struct trafcorrect * newitem;
if (argc < 5) {
if(DBGLEVEL == 1){
fprintf(stdout, "USE: trafcorrect m <service> <port> <coefficient>\n");
fprintf(stdout, "See documentation of traffic correct plugin.\n");
}
return 1;
}
newitem = (struct trafcorrect *)malloc(sizeof(struct trafcorrect));
newitem->next = NULL;
newitem->type = MULTIPLAY;
newitem->p_service = S_NOSERVICE;
if (!strcmp((char *)argv[2], (char *)"proxy")) newitem->p_service = S_PROXY;
if (!strcmp((char *)argv[2], (char *)"socks4")) newitem->p_service = S_SOCKS4;
if (!strcmp((char *)argv[2], (char *)"socks45")) newitem->p_service = S_SOCKS45;
if (!strcmp((char *)argv[2], (char *)"socks5")) newitem->p_service = S_SOCKS5;
if (!strcmp((char *)argv[2],(char *) "tcppm")) newitem->p_service = S_TCPPM;
if (!strcmp((char *)argv[2],(char *) "udppm")) newitem->p_service = S_UDPPM;
if (!strcmp((char *)argv[2], (char *)"admin")) newitem->p_service = S_ADMIN;
if (!strcmp((char *)argv[2], (char *)"pop3p")) newitem->p_service = S_POP3P;
newitem->port = atoi((char *)argv[3]);
newitem->coeff = atof((char *)argv[4]);
/* ïðîâåðêà íà êîððåêòíîñòü ââîäà */
if ((newitem->port>65535) || (newitem->coeff<=0) || (newitem->coeff>100)) {
free(newitem);
if(DBGLEVEL == 1)fprintf(stdout, "Port must be 0<p<65535 and coefficient must be 0<c<100.\n");
return 2;
}
addtrafcorrect(newitem);
return 0;
}
/* ðåæèì ó÷¸òà âõîäÿùèõ è èñõîäÿùèõ ïàêåòîâ */
if (!strcmp((char *)argv[1], "p")) {
struct trafcorrect * newitem;
if (argc < 5) {
if(DBGLEVEL == 1){
fprintf(stdout, "USE: trafcorrect p <service> <tcp/udp> <port> [packet size]\n");
fprintf(stdout, "See documentation of traffic correct plugin.\n");
}
return 1;
}
newitem = (struct trafcorrect *)malloc(sizeof(struct trafcorrect));
newitem->next = NULL;
newitem->type = IPCORRECT;
newitem->p_service = S_NOSERVICE;
if (!strstr((char *)argv[2], "proxy")) newitem->p_service = S_PROXY;
if (!strstr((char *)argv[2], "socks4")) newitem->p_service = S_SOCKS4;
if (!strstr((char *)argv[2], "socks45")) newitem->p_service = S_SOCKS45;
if (!strstr((char *)argv[2], "socks5")) newitem->p_service = S_SOCKS5;
if (!strstr((char *)argv[2], "tcppm")) newitem->p_service = S_TCPPM;
if (!strstr((char *)argv[2], "udppm")) newitem->p_service = S_UDPPM;
if (!strstr((char *)argv[2], "admin")) newitem->p_service = S_ADMIN;
if (!strstr((char *)argv[2], "pop3p")) newitem->p_service = S_POP3P;
newitem->con_type = TCP;
newitem->psize = 52;
if ((!strcmp((char *)argv[3], "udp")) && (newitem->p_service != S_PROXY) && (newitem->p_service != S_TCPPM) && (newitem->p_service != S_POP3P)) {
newitem->con_type = UDP;
newitem->psize = 48;
}
newitem->port = atoi((char *)argv[4]);
/* ïîñëåäíèé íåîáÿçàòåëüíûé ïàðàìåòð - ðàçìåð ïàêåòà */
if (argc >= 6) {
newitem->psize = atoi((char *)argv[5]);
}
if ((newitem->port>65535) || (newitem->psize<=0)) {
free(newitem);
if(DBGLEVEL == 1)fprintf(stdout, "Port must be 0<p<65535.\n");
return 2;
}
addtrafcorrect(newitem);
return 0;
}
if(DBGLEVEL == 1)fprintf(stdout, "See documentation of traffic correct plugin.\n");
return 1;
}
static unsigned short myhtons(unsigned short port) {
return (port << 8) | (port >> 8);
}
LOGFUNC origlogfunc;
void mylogfunc(struct clientparam * param, const unsigned char * pz) {
PROXYSERVICE g_s = S_NOSERVICE;
int port;
int rule = 0;
struct trafcorrect * starttrafcorrect = firsttrafcorrect;
#ifndef NOPSTDINT
uint64_t statssrv_before, statscli_before;
#else
unsigned long statssrv_before, statscli_before;
#endif
int ok = 0;
for (;starttrafcorrect != NULL; starttrafcorrect = starttrafcorrect->next) {
port = starttrafcorrect->port;
g_s = starttrafcorrect->p_service;
if (starttrafcorrect->p_service == S_NOSERVICE) g_s = param->service;
if (starttrafcorrect->port <= 0) port = myhtons(*SAPORT(&param->sinsr));
#ifndef NOPSTDINT
statssrv_before = param->statssrv64;
statscli_before = param->statscli64;
#else
statssrv_before = param->statssrv;
statscli_before = param->statscli;
#endif
rule++;
if (((g_s == param->service) && (port == myhtons(*SAPORT(&param->sinsr)))) ||
( ((starttrafcorrect->type == UDP) &&
((param->operation == UDPASSOC)||
(param->operation == DNSRESOLVE)||
(param->operation == BIND)||
(param->operation == ICMPASSOC))
)||(starttrafcorrect->type == TCP))) /* TCP support */
{
/* ôèëüòð ïîäîø¸ë. ìîæíî èçìåíÿòü çíà÷åíèå òðàôôèêà
äîìíîæàåì íà ÷èñëî */
if (starttrafcorrect->type == MULTIPLAY) {
#ifndef NOPSTDINT
param->statssrv64 = (unsigned)((double)param->statssrv64 *starttrafcorrect->coeff);
param->statscli64 = (unsigned)((double)param->statscli64 * starttrafcorrect->coeff);
#else
param->statssrv = (unsigned)((double)param->statssrv *starttrafcorrect->coeff);
param->statscli = (unsigned)((double)param->statscli * starttrafcorrect->coeff);
#endif
}
/* ñ ó÷¸òîì ïàêåòîâ */
if (starttrafcorrect->type == IPCORRECT) {
if (starttrafcorrect->con_type == TCP) {
#ifndef NOPSTDINT
param->statssrv64+=(param->nreads + 3*param->nconnects)*starttrafcorrect->psize;
param->statscli64+=(param->nwrites + 3*param->nconnects)*starttrafcorrect->psize;
#else
param->statssrv+=(param->nreads + 3*param->nconnects)*starttrafcorrect->psize;
param->statscli+=(param->nwrites + 3*param->nconnects)*starttrafcorrect->psize;
#endif
} else {
#ifndef NOPSTDINT
param->statssrv64+=param->nreads*starttrafcorrect->psize;
param->statscli64+=param->nwrites*starttrafcorrect->psize;
#else
param->statssrv+=param->nreads*starttrafcorrect->psize;
param->statscli+=param->nwrites*starttrafcorrect->psize;
#endif
}
}
if (DBGLEVEL == 1) {
#ifndef NOPSTDINT
fprintf(stdout, "Port=%hd; Before: srv=%"PRINTF_INT64_MODIFIER"d, cli=%"PRINTF_INT64_MODIFIER"d; After: srv=%"PRINTF_INT64_MODIFIER"d, cli=%"PRINTF_INT64_MODIFIER"d; nreads=%ld; nwrites=%ld; Rule=%d\n",myhtons(*SAPORT(&param->sinsr)), statssrv_before, statscli_before, param->statssrv64, param->statscli64,param->nreads,param->nwrites,rule);
#else
fprintf(stdout, "Port=%hd; Before: srv=%lu, cli=%lu; After: srv=%lu, cli=%lu; nreads=%ld; nwrites=%ld; Rule=%d\n",myhtons(param->sins.sin_port), statssrv_before, statscli_before, param->statssrv, param->statscli,param->nreads,param->nwrites,rule);
#endif
}
ok = 1;
break;
}
}
if ((!ok) && (DBGLEVEL == 1)) {
fprintf(stdout, "No rules specifed: service=%d, port=%d, operation=%d", param->service, *SAPORT(&param->sinsr),param->operation);
}
origlogfunc(param, pz);
}
#ifdef _WIN32
BOOL WINAPI DllMain( HINSTANCE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
if (ul_reason_for_call == DLL_PROCESS_DETACH) killtrafcorrect();
return TRUE;
}
#endif
#ifdef WATCOM
#pragma aux start "*" parm caller [ ] value struct float struct routine [eax] modify [eax ecx edx]
#undef PLUGINCALL
#define PLUGINCALL
#endif
PLUGINAPI int PLUGINCALL start(struct pluginlink * pluginlink, int argc, char** argv) {
struct commands * starthandler;
conf = pluginlink->conf;
commandhandlers = pluginlink->commandhandlers;
pl = pluginlink;
if (argc>1) {
/*for (int i = 0; i< argc; i++) fprintf(stdout,"%s ", argv[i]); */
if (!strcmp((char *)argv[1], "debug")) {
DBGLEVEL = 1;
fprintf(stdout, "Traffic correct plugin: debug mode enabled.\n");
}
}
if (already_loaded) {
killtrafcorrect();
return 0;
}
already_loaded = 1;
/* äîáàâëÿåì êîìàíäó "trafcorrect" */
starthandler = commandhandlers;
for ( ; starthandler->next; starthandler = starthandler->next);
trafcorrect_handler.next = NULL;
trafcorrect_handler.minargs = 1;
trafcorrect_handler.maxargs = 10;
trafcorrect_handler.command = "trafcorrect";
trafcorrect_handler.handler = h_trafcorrect;
starthandler->next = &trafcorrect_handler;
/* ïîäìåíÿåì conf->logfunc, ñ öåëüþ êîíòðîëèðîâàòü òðàôôèê */
origlogfunc = conf->logfunc;
conf->logfunc = mylogfunc;
return 0;
}
#ifdef __cplusplus
}
#endif