Added tcp forwarder for postfix
Signed-off-by: Tyrolyean <tyrolyean@tyrolyean.net>
This commit is contained in:
parent
bec5d91f70
commit
f0a93c5bc2
2
Makefile
2
Makefile
|
@ -33,7 +33,7 @@ $(DIRS_TARGET):
|
||||||
$(MKDIR_P) $@
|
$(MKDIR_P) $@
|
||||||
|
|
||||||
$(TARGET): $(OBJFILES)
|
$(TARGET): $(OBJFILES)
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ /usr/lib/libmilter.a
|
$(CC) $(LDFLAGS) -o $@ $^
|
||||||
|
|
||||||
$(BUILDDIR)/%.o: $(SRCDIR)/%.c
|
$(BUILDDIR)/%.o: $(SRCDIR)/%.c
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
$(CC) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#ifndef CONFIG_H
|
#ifndef CONFIG_H
|
||||||
#define CONFIG_H
|
#define CONFIG_H
|
||||||
|
|
||||||
extern char* socket_location;
|
#include <stdint.h>
|
||||||
|
|
||||||
|
extern uint16_t listen_port, forward_port;
|
||||||
|
|
||||||
#endif /* CONFIG_H */
|
#endif /* CONFIG_H */
|
||||||
|
|
|
@ -16,5 +16,4 @@
|
||||||
*/
|
*/
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
char* socket_location = "/var/run/mailattach";
|
uint16_t listen_port = 4269, forward_port = 4270;
|
||||||
|
|
||||||
|
|
191
src/main.c
191
src/main.c
|
@ -12,25 +12,196 @@
|
||||||
#include <sysexits.h>
|
#include <sysexits.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "attach.h"
|
#include "attach.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* error - wrapper for perror
|
||||||
|
*/
|
||||||
|
void error(char *msg) {
|
||||||
|
perror(msg);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct client_info {
|
||||||
|
int fd;
|
||||||
|
};
|
||||||
|
|
||||||
|
void* client_handle_async(void* params){
|
||||||
|
|
||||||
|
struct client_info * cli = params;
|
||||||
|
struct sockaddr_in serveraddr; /* server's addr */
|
||||||
|
int remote_fd;
|
||||||
|
|
||||||
|
remote_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (remote_fd < 0){
|
||||||
|
error("ERROR opening client socket");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* build the server's Internet address */
|
||||||
|
bzero((char *) &serveraddr, sizeof(serveraddr));
|
||||||
|
|
||||||
|
serveraddr.sin_family = AF_INET;
|
||||||
|
serveraddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||||
|
serveraddr.sin_port = htons(forward_port);
|
||||||
|
|
||||||
|
/* connect: create a connection with the server */
|
||||||
|
if (connect(remote_fd,(struct sockaddr *) &serveraddr,
|
||||||
|
sizeof(serveraddr)) < 0){
|
||||||
|
error("ERROR connecting");
|
||||||
|
}
|
||||||
|
|
||||||
|
int n; /* message byte size */
|
||||||
|
char buf[1024];
|
||||||
|
struct pollfd fds[2];
|
||||||
|
memset(fds, 0 , sizeof(fds));
|
||||||
|
fds[0].fd = cli->fd;
|
||||||
|
fds[0].events = POLLIN;
|
||||||
|
fds[1].fd = remote_fd;
|
||||||
|
fds[1].events = POLLIN;
|
||||||
|
|
||||||
|
int timeout = (10 * 1000); /* 10 seconds */
|
||||||
|
|
||||||
|
while(poll(fds, 2, timeout) > 0){
|
||||||
|
for(size_t i = 0; i < 2; i++){
|
||||||
|
if(!(fds[i].revents & POLLIN)){
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
bzero(buf, sizeof(buf));
|
||||||
|
n = read(fds[i].fd, buf, sizeof(buf));
|
||||||
|
if (n <= 0) {
|
||||||
|
goto closeup;
|
||||||
|
}
|
||||||
|
printf("%lu: %s\n", i, buf);
|
||||||
|
write((fds[!i].fd), buf, n);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closeup:
|
||||||
|
|
||||||
|
printf("Disconnecting clients");
|
||||||
|
close(cli->fd);
|
||||||
|
close(remote_fd);
|
||||||
|
free(cli);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[]){
|
int main(int argc, char* argv[]){
|
||||||
|
|
||||||
FILE* logfile = fopen("/tmp/shit", "a+");
|
printf("INIT\n");
|
||||||
|
printf("Arguments passed on:\n");
|
||||||
fprintf(logfile, "INIT\n");
|
for(int i = 0; i < argc; i++){
|
||||||
fprintf(logfile, "Arguments passed on:\n");
|
printf("\t%i:%s\n",i, argv[i]);
|
||||||
for(size_t i = 0; i < argc; i++){
|
|
||||||
fprintf(logfile, "\t%lu:%s\n",i, argv[i]);
|
|
||||||
}
|
}
|
||||||
char input[1024];
|
|
||||||
fread(input, sizeof(input), 1, stdin);
|
|
||||||
fprintf(logfile, input);
|
|
||||||
|
|
||||||
fclose(logfile);
|
int parentfd; /* parent socket */
|
||||||
|
int childfd; /* child socket */
|
||||||
|
socklen_t clientlen; /* byte size of client's address */
|
||||||
|
struct sockaddr_in serveraddr; /* server's addr */
|
||||||
|
struct sockaddr_in clientaddr; /* client addr */
|
||||||
|
struct hostent *hostp; /* client host info */
|
||||||
|
char *hostaddrp; /* dotted decimal host addr string */
|
||||||
|
int optval; /* flag value for setsockopt */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* socket: create the parent socket
|
||||||
|
*/
|
||||||
|
parentfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (parentfd < 0){
|
||||||
|
error("ERROR opening socket");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* setsockopt: Handy debugging trick that lets
|
||||||
|
* us rerun the server immediately after we kill it;
|
||||||
|
* otherwise we have to wait about 20 secs.
|
||||||
|
* Eliminates "ERROR on binding: Address already in use" error.
|
||||||
|
*/
|
||||||
|
optval = 1;
|
||||||
|
setsockopt(parentfd, SOL_SOCKET, SO_REUSEADDR,
|
||||||
|
(const void *)&optval , sizeof(int));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* build the server's Internet address
|
||||||
|
*/
|
||||||
|
bzero((char *) &serveraddr, sizeof(serveraddr));
|
||||||
|
|
||||||
|
/* this is an Internet address */
|
||||||
|
serveraddr.sin_family = AF_INET;
|
||||||
|
|
||||||
|
/* let the system figure out our IP address */
|
||||||
|
serveraddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||||
|
|
||||||
|
/* this is the port we will listen on */
|
||||||
|
serveraddr.sin_port = htons((unsigned short)listen_port);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* bind: associate the parent socket with a port
|
||||||
|
*/
|
||||||
|
if (bind(parentfd, (struct sockaddr *) &serveraddr,
|
||||||
|
sizeof(serveraddr)) < 0) {
|
||||||
|
error("ERROR on binding");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* listen: make this socket ready to accept connection requests
|
||||||
|
*/
|
||||||
|
if (listen(parentfd, 5) < 0) /* allow 5 requests to queue up */
|
||||||
|
error("ERROR on listen");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* main loop: wait for a connection request, echo input line,
|
||||||
|
* then close connection.
|
||||||
|
*/
|
||||||
|
clientlen = sizeof(clientaddr);
|
||||||
|
char hostaddr_str[20];
|
||||||
|
inet_ntop(AF_INET,(struct sockaddr *) &serveraddr, hostaddr_str, 20);
|
||||||
|
printf("Listening for clients on port %u\n", listen_port);
|
||||||
|
while (1) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* accept: wait for a connection request
|
||||||
|
*/
|
||||||
|
childfd = accept(parentfd, (struct sockaddr *) &clientaddr, &clientlen);
|
||||||
|
if (childfd < 0)
|
||||||
|
error("ERROR on accept");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* gethostbyaddr: determine who sent the message
|
||||||
|
*/
|
||||||
|
hostp = gethostbyaddr((const char *)&clientaddr.sin_addr.s_addr,
|
||||||
|
sizeof(clientaddr.sin_addr.s_addr), AF_INET);
|
||||||
|
if (hostp == NULL)
|
||||||
|
error("ERROR on gethostbyaddr");
|
||||||
|
hostaddrp = inet_ntoa(clientaddr.sin_addr);
|
||||||
|
if (hostaddrp == NULL)
|
||||||
|
error("ERROR on inet_ntoa\n");
|
||||||
|
printf("server established connection with %s (%s) fd %i\n",
|
||||||
|
hostp->h_name, hostaddrp, childfd);
|
||||||
|
|
||||||
|
struct client_info* cli = malloc(sizeof(struct client_info));
|
||||||
|
memset(cli, 0, sizeof(struct client_info));
|
||||||
|
cli->fd = childfd;
|
||||||
|
pthread_t executing_thread;
|
||||||
|
int status = pthread_create(&executing_thread, NULL,
|
||||||
|
client_handle_async, cli);
|
||||||
|
if(status < 0){
|
||||||
|
error("Failed to create thread");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return EX_TEMPFAIL;
|
return EX_TEMPFAIL;
|
||||||
|
|
Loading…
Reference in New Issue