1 /*
2     VTun - Virtual Tunnel over TCP/IP network.
3 
4     Copyright (C) 1998-2016  Maxim Krasnyansky <max_mk@yahoo.com>
5 
6     VTun has been derived from VPPP package by Maxim Krasnyansky.
7 
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12 
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17  */
18 
19 /*
20  * $Id: client.c,v 1.11.2.4 2016/10/01 21:27:51 mtbishop Exp $
21  */
22 
23 #include "config.h"
24 #include "vtun_socks.h"
25 
26 #include <stdio.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <signal.h>
31 #include <fcntl.h>
32 #include <syslog.h>
33 
34 #ifdef HAVE_NETINET_IN_H
35 #include <netinet/in.h>
36 #endif
37 
38 #ifdef HAVE_ARPA_INET_H
39 #include <arpa/inet.h>
40 #endif
41 
42 #include "vtun.h"
43 #include "lib.h"
44 #include "llist.h"
45 #include "auth.h"
46 #include "compat.h"
47 #include "netlib.h"
48 
49 static volatile sig_atomic_t client_term;
sig_term(int sig)50 static void sig_term(int sig)
51 {
52      vtun_syslog(LOG_INFO,"Terminated");
53      client_term = VTUN_SIG_TERM;
54 }
55 
client(struct vtun_host * host)56 void client(struct vtun_host *host)
57 {
58      struct sockaddr_in my_addr,svr_addr;
59      struct sigaction sa;
60      int s, opt, reconnect;
61 
62      vtun_syslog(LOG_INFO,"VTun client ver %s started",VTUN_VER);
63 
64      memset(&sa,0,sizeof(sa));
65      sa.sa_handler=SIG_IGN;
66      sa.sa_flags = SA_NOCLDWAIT;
67      sigaction(SIGHUP,&sa,NULL);
68      sigaction(SIGQUIT,&sa,NULL);
69      sigaction(SIGPIPE,&sa,NULL);
70      sigaction(SIGCHLD,&sa,NULL);
71 
72      sa.sa_handler=sig_term;
73      sigaction(SIGTERM,&sa,NULL);
74      sigaction(SIGINT,&sa,NULL);
75 
76      client_term = 0; reconnect = 0;
77      while( (!client_term) || (client_term == VTUN_SIG_HUP) ){
78 	if( reconnect && (client_term != VTUN_SIG_HUP) ){
79 	   if( vtun.persist || host->persist ){
80 	      /* Persist mode. Sleep and reconnect. */
81 	      sleep(5);
82            } else {
83 	      /* Exit */
84 	      break;
85 	   }
86 	} else {
87 	   reconnect = 1;
88         }
89 
90 	set_title("%s init initializing", host->host);
91 
92 	/* Set server address */
93         if( server_addr(&svr_addr, host) < 0 )
94 	   continue;
95 
96 	/* Set local address */
97 	if( local_addr(&my_addr, host, 0) < 0 )
98 	   continue;
99 
100 	/* We have to create socket again every time
101 	 * we want to connect, since STREAM sockets
102 	 * can be successfully connected only once.
103 	 */
104         if( (s = socket(AF_INET,SOCK_STREAM,0))==-1 ){
105 	   vtun_syslog(LOG_ERR,"Can't create socket. %s(%d)",
106 		strerror(errno), errno);
107 	   continue;
108         }
109 
110 	/* Required when client is forced to bind to specific port */
111         opt=1;
112         setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
113 
114         if( bind(s,(struct sockaddr *)&my_addr,sizeof(my_addr)) ){
115 	   vtun_syslog(LOG_ERR,"Can't bind socket. %s(%d)",
116 		strerror(errno), errno);
117 	   continue;
118         }
119 
120         /*
121          * Clear speed and flags which will be supplied by server.
122          */
123         host->spd_in = host->spd_out = 0;
124         host->flags &= VTUN_CLNT_MASK;
125 
126 	io_init();
127 
128 	set_title("%s connecting to %s", host->host, vtun.svr_name);
129 	if (!vtun.quiet)
130 	   vtun_syslog(LOG_INFO,"Connecting to %s", vtun.svr_name);
131 
132         if( connect_t(s,(struct sockaddr *) &svr_addr, host->timeout) ){
133 	   if (!vtun.quiet || errno != ETIMEDOUT)
134 	      vtun_syslog(LOG_INFO,"Connect to %s failed. %s(%d)", vtun.svr_name,
135 					strerror(errno), errno);
136         } else {
137 	   if( auth_client(s, host) ){
138 	      vtun_syslog(LOG_INFO,"Session %s[%s] opened",host->host,vtun.svr_name);
139 
140  	      host->rmt_fd = s;
141 
142 	      /* Start the tunnel */
143 	      client_term = tunnel(host);
144 
145 	      vtun_syslog(LOG_INFO,"Session %s[%s] closed",host->host,vtun.svr_name);
146 	   } else {
147 	      vtun_syslog(LOG_INFO,"Connection denied by %s",vtun.svr_name);
148 	   }
149 	}
150 	close(s);
151 	free_sopt(&host->sopt);
152      }
153 
154      vtun_syslog(LOG_INFO, "Exit");
155      return;
156 }
157