mirror of https://github.com/bol-van/zapret/
17 changed files with 1128 additions and 717 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,30 @@ |
|||
#pragma once |
|||
|
|||
#include <stdbool.h> |
|||
#include <net/if.h> |
|||
#include <stdint.h> |
|||
#include "strpool.h" |
|||
|
|||
enum splithttpreq { split_none = 0, split_method, split_host }; |
|||
|
|||
struct params_s |
|||
{ |
|||
char bindaddr[64],bindiface[IFNAMSIZ]; |
|||
bool bind_if6; |
|||
bool bindll,bindll_force; |
|||
int bind_wait_ifup,bind_wait_ip,bind_wait_ip_ll; |
|||
uid_t uid; |
|||
gid_t gid; |
|||
uint16_t port; |
|||
bool daemon; |
|||
bool hostcase, hostdot, hosttab, hostnospace, methodspace, methodeol, unixeol; |
|||
char hostspell[4]; |
|||
enum splithttpreq split_http_req; |
|||
int split_pos; |
|||
int maxconn; |
|||
char hostfile[256]; |
|||
char pidfile[256]; |
|||
strpool *hostlist; |
|||
}; |
|||
|
|||
extern struct params_s params; |
@ -0,0 +1,182 @@ |
|||
#include "tamper.h" |
|||
#include "params.h" |
|||
#include <string.h> |
|||
#include <stdio.h> |
|||
|
|||
char *find_bin(void *data, size_t len, const void *blk, size_t blk_len) |
|||
{ |
|||
while (len >= blk_len) |
|||
{ |
|||
if (!memcmp(data, blk, blk_len)) |
|||
return data; |
|||
data = (char*)data + 1; |
|||
len--; |
|||
} |
|||
return NULL; |
|||
} |
|||
|
|||
// pHost points to "Host: ..."
|
|||
bool find_host(char **pHost,char *buf,size_t bs) |
|||
{ |
|||
if (!*pHost) |
|||
{ |
|||
*pHost = find_bin(buf, bs, "\nHost: ", 7); |
|||
if (*pHost) (*pHost)++; |
|||
printf("Found Host: at pos %zu\n",*pHost - buf); |
|||
} |
|||
return !!*pHost; |
|||
} |
|||
|
|||
static const char *http_methods[] = { "GET /","POST /","HEAD /","OPTIONS /","PUT /","DELETE /","CONNECT /","TRACE /",NULL }; |
|||
void modify_tcp_segment(char *segment,size_t *size,size_t *split_pos) |
|||
{ |
|||
char *p, *pp, *pHost = NULL; |
|||
size_t method_len = 0, pos; |
|||
const char **method; |
|||
bool bIsHttp = false, bBypass = false; |
|||
char bRemovedHostSpace = 0; |
|||
char Host[128]; |
|||
|
|||
*split_pos=0; |
|||
|
|||
for (method = http_methods; *method; method++) |
|||
{ |
|||
method_len = strlen(*method); |
|||
if (method_len <= *size && !memcmp(segment, *method, method_len)) |
|||
{ |
|||
bIsHttp = true; |
|||
method_len -= 2; // "GET /" => "GET"
|
|||
break; |
|||
} |
|||
} |
|||
if (bIsHttp) |
|||
{ |
|||
printf("Data block looks like http request start : %s\n", *method); |
|||
// cpu saving : we search host only if and when required. we do not research host every time we need its position
|
|||
if (params.hostlist && find_host(&pHost,segment,*size)) |
|||
{ |
|||
bool bInHostList = false; |
|||
p = pHost + 6; |
|||
while (p < (segment + *size) && (*p == ' ' || *p == '\t')) p++; |
|||
pp = p; |
|||
while (pp < (segment + *size) && (pp - p) < (sizeof(Host) - 1) && *pp != '\r' && *pp != '\n') pp++; |
|||
memcpy(Host, p, pp - p); |
|||
Host[pp - p] = '\0'; |
|||
printf("Requested Host is : %s\n", Host); |
|||
for(p = Host; *p; p++) *p=tolower(*p); |
|||
p = Host; |
|||
while (p) |
|||
{ |
|||
bInHostList = StrPoolCheckStr(params.hostlist, p); |
|||
printf("Hostlist check for %s : %s\n", p, bInHostList ? "positive" : "negative"); |
|||
if (bInHostList) break; |
|||
p = strchr(p, '.'); |
|||
if (p) p++; |
|||
} |
|||
bBypass = !bInHostList; |
|||
} |
|||
if (!bBypass) |
|||
{ |
|||
if (params.unixeol) |
|||
{ |
|||
p = pp = segment; |
|||
while (p = find_bin(p, segment + *size - p, "\r\n", 2)) |
|||
{ |
|||
*p = '\n'; p++; |
|||
memmove(p, p + 1, segment + *size - p - 1); |
|||
(*size)--; |
|||
if (pp == (p - 1)) |
|||
{ |
|||
// probably end of http headers
|
|||
printf("Found double EOL at pos %zu. Stop replacing.\n", pp - segment); |
|||
break; |
|||
} |
|||
pp = p; |
|||
} |
|||
pHost = NULL; // invalidate
|
|||
} |
|||
|
|||
if (params.methodspace) |
|||
{ |
|||
// we only work with data blocks looking as HTTP query, so method is at the beginning
|
|||
printf("Adding extra space after method\n"); |
|||
p = segment + method_len + 1; |
|||
pos = method_len + 1; |
|||
memmove(p + 1, p, *size - pos); |
|||
*p = ' '; // insert extra space
|
|||
(*size)++; // block will grow by 1 byte
|
|||
if (pHost) pHost++; // Host: position will move by 1 byte
|
|||
} |
|||
if ((params.hostdot || params.hosttab) && find_host(&pHost,segment,*size)) |
|||
{ |
|||
p = pHost + 6; |
|||
while (p < (segment + *size) && *p != '\r' && *p != '\n') p++; |
|||
if (p < (segment + *size)) |
|||
{ |
|||
pos = p - segment; |
|||
printf("Adding %s to host name at pos %zu\n", params.hostdot ? "dot" : "tab", pos); |
|||
memmove(p + 1, p, *size - pos); |
|||
*p = params.hostdot ? '.' : '\t'; // insert dot or tab
|
|||
(*size)++; // block will grow by 1 byte
|
|||
} |
|||
} |
|||
if (params.hostnospace && find_host(&pHost,segment,*size) && pHost[5] == ' ') |
|||
{ |
|||
p = pHost + 6; |
|||
pos = p - segment; |
|||
printf("Removing space before host name at pos %zu\n", pos); |
|||
memmove(p - 1, p, *size - pos); |
|||
(*size)--; // block will shrink by 1 byte
|
|||
bRemovedHostSpace = 1; |
|||
} |
|||
if (!params.split_pos) |
|||
{ |
|||
switch (params.split_http_req) |
|||
{ |
|||
case split_method: |
|||
*split_pos = method_len - 1; |
|||
break; |
|||
case split_host: |
|||
if (find_host(&pHost,segment,*size)) |
|||
*split_pos = pHost + 6 - bRemovedHostSpace - segment; |
|||
break; |
|||
} |
|||
} |
|||
if (params.hostcase && find_host(&pHost,segment,*size)) |
|||
{ |
|||
printf("Changing 'Host:' => '%c%c%c%c:' at pos %zu\n", params.hostspell[0], params.hostspell[1], params.hostspell[2], params.hostspell[3], pHost - segment); |
|||
memcpy(pHost, params.hostspell, 4); |
|||
} |
|||
if (params.methodeol) |
|||
{ |
|||
printf("Adding EOL before method\n"); |
|||
if (params.unixeol) |
|||
{ |
|||
memmove(segment + 1, segment, *size); |
|||
(*size)++;; |
|||
segment[0] = '\n'; |
|||
if (*split_pos) (*split_pos)++; |
|||
} |
|||
else |
|||
{ |
|||
memmove(segment + 2, segment, *size); |
|||
*size += 2; |
|||
segment[0] = '\r'; |
|||
segment[1] = '\n'; |
|||
if (*split_pos) *split_pos += 2; |
|||
} |
|||
} |
|||
if (params.split_pos && params.split_pos < *size) *split_pos = params.split_pos; |
|||
} |
|||
else |
|||
{ |
|||
printf("Not acting on this request\n"); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
printf("Data block does not look like http request start\n"); |
|||
// this is the only parameter applicable to non-http block (may be https ?)
|
|||
if (params.split_pos && params.split_pos < *size) *split_pos = params.split_pos; |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
#pragma once |
|||
|
|||
#include <stdbool.h> |
|||
#include <sys/types.h> |
|||
|
|||
char *find_bin(void *data, size_t len, const void *blk, size_t blk_len); |
|||
bool find_host(char **pHost,char *buf,size_t bs); |
|||
void modify_tcp_segment(char *segment,size_t *size,size_t *split_pos); |
@ -1,37 +1,3 @@ |
|||
#ifndef TPROXY_EXAMPLE_H |
|||
#define TPROXY_EXAMPLE_H |
|||
#pragma once |
|||
|
|||
#include <stdint.h> |
|||
#include <sys/queue.h> |
|||
|
|||
#define BACKLOG 10 |
|||
#define MAX_EPOLL_EVENTS BACKLOG |
|||
#define IP_TRANSPARENT 19 //So that application compiles on OpenWRT
|
|||
#define SPLICE_LEN 65536 |
|||
#define DEFAULT_MAX_CONN 512 |
|||
|
|||
//Three different states of a connection
|
|||
enum{ |
|||
CONN_AVAILABLE=0, |
|||
CONN_CLOSED, |
|||
}; |
|||
typedef uint8_t conn_state_t; |
|||
|
|||
struct tproxy_conn{ |
|||
int local_fd; //Connection to host on local network
|
|||
int remote_fd; //Connection to remote host
|
|||
int splice_pipe[2]; //Have pipes per connection for now. Multiplexing
|
|||
//different connections onto pipes is tricky, for
|
|||
//example when flushing pipe after one connection has
|
|||
//failed.
|
|||
conn_state_t state; |
|||
|
|||
//Create the struct which contains ptrs to next/prev element
|
|||
TAILQ_ENTRY(tproxy_conn) conn_ptrs; |
|||
}; |
|||
typedef struct tproxy_conn tproxy_conn_t; |
|||
|
|||
//Define the struct tailhead (code in sys/queue.h is quite intuitive)
|
|||
//Use tail queue for efficient delete
|
|||
TAILQ_HEAD(tailhead, tproxy_conn); |
|||
#endif |
|||
void dohup(); |
|||
|
File diff suppressed because it is too large
@ -1,13 +1,61 @@ |
|||
#ifndef TPROXY_TEST_CONN_H |
|||
#define TPROXY_TEST_CONN_H |
|||
#pragma once |
|||
|
|||
#include "tpws.h" |
|||
#include <stdbool.h> |
|||
#include <sys/queue.h> |
|||
|
|||
int check_local_ip(const struct sockaddr *saddr); |
|||
uint16_t saport(const struct sockaddr *sa); |
|||
tproxy_conn_t* add_tcp_connection(int efd, struct tailhead *conn_list, |
|||
int local_fd, uint16_t listen_port); |
|||
void free_conn(tproxy_conn_t *conn); |
|||
int8_t check_connection_attempt(tproxy_conn_t *conn, int efd); |
|||
#endif |
|||
#define BACKLOG 10 |
|||
#define MAX_EPOLL_EVENTS BACKLOG |
|||
#define IP_TRANSPARENT 19 //So that application compiles on OpenWRT
|
|||
#define SPLICE_LEN 16384 |
|||
#define DEFAULT_MAX_CONN 512 |
|||
|
|||
int event_loop(int listen_fd); |
|||
|
|||
//Three different states of a connection
|
|||
enum{ |
|||
CONN_UNAVAILABLE=0, // connecting
|
|||
CONN_AVAILABLE, // operational
|
|||
CONN_RDHUP, // received RDHUP, only sending unsent buffers. more RDHUPs are blocked
|
|||
CONN_CLOSED // will be deleted soon
|
|||
}; |
|||
typedef uint8_t conn_state_t; |
|||
|
|||
struct send_buffer |
|||
{ |
|||
char *data; |
|||
size_t len,pos; |
|||
}; |
|||
typedef struct send_buffer send_buffer_t; |
|||
|
|||
struct tproxy_conn |
|||
{ |
|||
bool remote; // false - accepted, true - connected
|
|||
int efd; // epoll fd
|
|||
int fd; |
|||
int splice_pipe[2]; |
|||
conn_state_t state; |
|||
|
|||
struct tproxy_conn *partner; // other leg
|
|||
//Create the struct which contains ptrs to next/prev element
|
|||
TAILQ_ENTRY(tproxy_conn) conn_ptrs; |
|||
|
|||
bool bFlowIn,bFlowOut, bFlowInPrev,bFlowOutPrev, bPrevRdhup; |
|||
|
|||
// total read,write
|
|||
size_t trd,twr; |
|||
|
|||
// connection is either spliced or send/recv
|
|||
// spliced connection have pipe buffering but also can have send_buffer's
|
|||
// pipe buffer comes first, then send_buffer's from 0 to countof(wr_buf)-1
|
|||
// send/recv connection do not have pipe and wr_unsent is meaningless
|
|||
ssize_t wr_unsent; // unsent bytes in the pipe
|
|||
// buffer 1 : send before split_pos
|
|||
// buffer 2 : send after split_pos
|
|||
// buffer 3 : after RDHUP read all and buffer to the partner
|
|||
struct send_buffer wr_buf[3]; |
|||
}; |
|||
typedef struct tproxy_conn tproxy_conn_t; |
|||
|
|||
//Define the struct tailhead (code in sys/queue.h is quite intuitive)
|
|||
//Use tail queue for efficient delete
|
|||
TAILQ_HEAD(tailhead, tproxy_conn); |
|||
|
Loading…
Reference in new issue