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