118 lines
2.4 KiB
C
118 lines
2.4 KiB
C
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <unistd.h>
|
||
|
|
||
|
#include "configfile.h"
|
||
|
#include "connection.h"
|
||
|
#include "event.h"
|
||
|
#include "list.h"
|
||
|
#include "logging.h"
|
||
|
#include "network.h"
|
||
|
|
||
|
static LIST_HEAD(connection_list);
|
||
|
|
||
|
static int server_handler(int fd, void *privdata)
|
||
|
{
|
||
|
struct connection *con = (struct connection *)privdata;
|
||
|
char buf[256];
|
||
|
|
||
|
int len = read(fd, buf, sizeof(buf));
|
||
|
if (len <= 0) {
|
||
|
list_del(&con->list);
|
||
|
destroy_connection(con);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
write(con->src_fd, buf, len);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int client_handler(int fd, void *privdata)
|
||
|
{
|
||
|
struct connection *con = (struct connection *)privdata;
|
||
|
char buf[256];
|
||
|
|
||
|
int len = read(fd, buf, sizeof(buf));
|
||
|
if (len <= 0) {
|
||
|
list_del(&con->list);
|
||
|
destroy_connection(con);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
if (con->dst_fd != -1) {
|
||
|
write(con->dst_fd, buf, len);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// check destination
|
||
|
int sock = tcp_connect_socket(&con->dst_addr);
|
||
|
if (sock < 0) {
|
||
|
list_del(&con->list);
|
||
|
destroy_connection(con);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
event_add_readfd(sock, server_handler, con);
|
||
|
log_print(LOG_INFO, "forwarding to %s", get_sockaddr_buf(&con->dst_addr));
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int listen_handler(int fd, void *privdata)
|
||
|
{
|
||
|
struct connection *con = malloc(sizeof(struct connection));
|
||
|
if (con == NULL) {
|
||
|
log_print(LOG_WARN, "listen_handler(): out of memory");
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int i = sizeof(con->src_addr);
|
||
|
con->src_fd = accept(fd, (struct sockaddr *)&con->src_addr, &i);
|
||
|
if (con->src_fd < 0) {
|
||
|
free(con);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
con->dst_fd = -1;
|
||
|
con->login_time = con->idle_time = time(NULL);
|
||
|
|
||
|
log_print(LOG_INFO, "accepted connection from %s", get_sockaddr_buf(&con->src_addr));
|
||
|
|
||
|
list_add_tail(&con->list, &connection_list);
|
||
|
event_add_readfd(con->src_fd, client_handler, con);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int listen_init(const char *value, void *privdata)
|
||
|
{
|
||
|
struct sockaddr_in addr;
|
||
|
|
||
|
if (parse_saddr(value, &addr) == -1) {
|
||
|
log_print(LOG_WARN, "invalid listen addr: '%s'", value);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
int sock = tcp_listen_socket(&addr, 10);
|
||
|
if (sock < 0)
|
||
|
return -1;
|
||
|
|
||
|
event_add_readfd(sock, listen_handler, NULL);
|
||
|
log_print(LOG_INFO, "listen on %s", get_sockaddr_buf(&addr));
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int main(int argc, char *argv[])
|
||
|
{
|
||
|
if (config_parse("telnetproxy.conf") == -1)
|
||
|
return -1;
|
||
|
|
||
|
int cnt = config_get_strings("global", "listen", listen_init, NULL);
|
||
|
if (cnt <= 0) {
|
||
|
log_print(LOG_ERROR, "no listen sockets defined!");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
event_loop();
|
||
|
|
||
|
return 0;
|
||
|
}
|