forked from semigodking/redsocks
-
Notifications
You must be signed in to change notification settings - Fork 5
/
direct.c
92 lines (80 loc) · 2.94 KB
/
direct.c
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
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/* redsocks2 - transparent TCP-to-proxy redirector
* Copyright (C) 2013-2017 Zhuofei Wang <[email protected]>
*
* This code is based on redsocks project developed by Leonid Evdokimov.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "parser.h"
#include "log.h"
#include "main.h"
#include "redsocks.h"
#include "utils.h"
int redsocks_start_relay(redsocks_client *client);
void redsocks_touch_client(redsocks_client *client);
void redsocks_event_error(struct bufferevent *buffev, short what, void *_arg);
void redsocks_relay_connected(struct bufferevent *buffev, void *_arg);
static void direct_relay_init(redsocks_client *client)
{
client->state = 0;
}
static void direct_relay_fini(redsocks_client *client)
{
}
static void direct_write_cb(struct bufferevent *buffev, void *_arg)
{
redsocks_client *client = _arg;
redsocks_touch_client(client);
if (client->state == 0)
{
client->state = 1;
if (redsocks_start_relay(client))
// Failed to start relay. Connection is dropped.
return;
// Write any data received from client to relay
struct evbuffer * input = bufferevent_get_input(client->client);
if (evbuffer_get_length(input))
if (bufferevent_write_buffer(client->relay, input) == -1)
redsocks_log_errno(client, LOG_ERR, "bufferevent_write_buffer");
}
}
static int direct_connect_relay(redsocks_client *client)
{
char * interface = client->instance->config.interface;
struct timeval tv = {client->instance->config.timeout, 0};
// Allowing binding relay socket to specified IP for outgoing connections
client->relay = red_connect_relay(interface, &client->destaddr, NULL,
redsocks_relay_connected, redsocks_event_error, client, &tv);
if (!client->relay)
{
redsocks_log_errno(client, LOG_ERR, "red_connect_relay");
redsocks_drop_client(client);
return -1;
}
return 0;
}
relay_subsys direct_connect_subsys =
{
.name = "direct",
.payload_len = 0,
.instance_payload_len = 0,
.writecb = direct_write_cb,
.init = direct_relay_init,
.fini = direct_relay_fini,
.connect_relay = direct_connect_relay,
};
/* vim:set tabstop=4 softtabstop=4 shiftwidth=4: */
/* vim:set foldmethod=marker foldlevel=32 foldmarker={,}: */