/*
 * Worldvisions Tunnel Vision Software:
 *   Copyright (C) 1998 Worldvisions Computer Technology, Inc.
 * 
 * Listen on a port waiting for incoming VPN connections; also, make
 * outgoing connections to remote hosts as specified on the command line.
 * 
 * This uses the proprietary Tunnel Vision protocol and SSLeay encryption
 * routines.
 */
#include "wvtunnel.h"
#include "wvresolver.h"
#include <signal.h>


volatile bool want_to_die = false;


static void signal_handler(int)
{
    want_to_die = true;
}


int main(int argc, char **argv)
{
    WvStreamList l;
    WvConf cfg("/etc/tunnelv.conf");

    free(malloc(1));
    
    if (argc < 2 || argc > 3)
    {
	fprintf(stderr,
		"Usage: %s <listenport>\n"
		"   or: %s <serverhost> <serverport>\n", argv[0], argv[0]);
	return 1;
    }
    
    WvLog log("tunnelv", WvLog::Info);

    if (argc == 2)  // server mode
    {
	WvIPPortAddr listenport("0.0.0.0", atoi(argv[1]));
	WvTunnelListener *listener = new WvTunnelListener(listenport, &l, cfg);
    
	if (!listener->isok())
	{
	    log(WvLog::Error, "listener(%s): %s\nIs tunnelv already running?\n",
		listenport, l.errstr());
	    return 1;
	}
    
	log("Waiting for connections on %s\n", listenport);
	l.append(listener, true);
    }
    else  // client mode
    {
	int result;
	WvResolver dns;
	const WvIPAddr *ip;
    
	log("Looking up %s...", argv[1]);
	result = dns.findaddr(30*1000, argv[1], &ip);
	if (!result)
	{
	    log(WvLog::Error, "no such host!  Skipping.\n");
	}
	else if (result < 0)
	{
	    log(WvLog::Error, "timed out!  Skipping.\n");
	}
	else
	{
	    log("%s.  Connecting...\n", *ip);
	    WvStream *s = new WvTunnel(new WvTCPConn(
				           WvIPPortAddr(*ip, atoi(argv[2]))),
				       false, cfg);
	    l.append(s, true);
	}
    }
    
    signal(SIGINT, signal_handler);
    signal(SIGTERM, signal_handler);
    signal(SIGPIPE, SIG_IGN);
    
    // main loop
    while (!want_to_die && l.count())
    {
	if (l.select(1000))
	    l.callback();
    }
    
    return 0;
}
