/*
 * Copyright (c) 2001-2007, OpenFWTK Development Group
 * All rights reserved. See LICENSE.
 */

/*
 *  OpenFWTK project generation 2 API supplementary functions
 *  
 *  (C) Copyright 2001,2002 ArkanoiD <ark@eltex.ru>
 */

/*
 *  proxy_tunnel() implements generic tunnel between server and
 *  client sockets performing authomatic accounting data update.
 */

#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <syslog.h>
#include <string.h>
#include <strings.h>
#include "firewall.h"
#include "firewall2.h"

#ifndef MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif

static char* moduleId ATTR_UNUSED = "$Id: tunnel.c,v 1.5 2007/09/10 02:49:13 arkenoi Exp $";

void
proxy_tunnel(int socket_i, int socket_o)
{
	fd_set		rdy;
	fd_set		iced;
	struct timeval	timo;
	int		x;
	char		buf[1024 * 4];


	FD_ZERO(&iced);
	FD_SET(socket_i,&iced);
	FD_SET(socket_o,&iced);
	timo.tv_sec = proxy_timeout;
	timo.tv_usec = 0L;

	while(1) {
		(void)bcopy(&iced,&rdy,sizeof(fd_set));

		if(select(MAX(socket_i,socket_o)+1,&rdy,NULL,NULL,&timo) <= 0) {
			syslog(LLEV,"connection timeout: %u sec",(u_int) timo.tv_sec);
			break;
		}

		proxy_update_status();

		if(FD_ISSET(socket_i,&rdy)) {
			if((x = read(socket_i,buf,sizeof(buf))) <= 0)
				break;
			if(sowrite(socket_o,buf,x) != x)
				break;
			proxy_stats.outbytes += x;
		}
		if(FD_ISSET(socket_o,&rdy)) {
			if((x = read(socket_o,buf,sizeof(buf))) <= 0)
				break;
			if(sowrite(socket_i,buf,x) != x)
				break;
			proxy_stats.inbytes += x;
		}
	}
	return;
}

