forked from larsbrinkhoff/httptunnel
-
Notifications
You must be signed in to change notification settings - Fork 0
/
common.h
173 lines (147 loc) · 3.5 KB
/
common.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/*
common.h
Copyright (C) 1999 Lars Brinkhoff. See COPYING for terms and conditions.
*/
#ifndef COMMON_H
#define COMMON_H
#include "config.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio_.h>
#include <unistd_.h>
#include <string.h>
#include <syslog_.h>
#include <getopt.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdarg.h>
#include "tunnel.h"
#define DEFAULT_HOST_PORT 8888
#define DEFAULT_CONTENT_LENGTH (100 * 1024) /* bytes */
#define DEFAULT_KEEP_ALIVE 5 /* seconds */
#define DEFAULT_MAX_CONNECTION_AGE 300 /* seconds */
#define BUG_REPORT_EMAIL "[email protected]"
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#if defined (LOG_ERR) && !defined (LOG_ERROR)
#define LOG_ERROR LOG_ERR
#endif
extern int debug_level;
extern FILE *debug_file;
extern void log_exit (int status);
extern void log_notice (char *fmt0, ...);
extern void log_error (char *fmt0, ...);
#ifdef DEBUG_MODE
extern void log_debug (char *fmt0, ...);
extern void log_verbose (char *fmt0, ...);
extern void log_annoying (char *fmt0, ...);
#else
static inline void log_debug () {}
static inline void log_verbose () {}
static inline void log_annoying () {}
#endif
extern int server_socket (struct in_addr addr, int port, int backlog);
extern int set_address (struct sockaddr_in *address,
const char *host, int port);
extern int open_device (char *device);
extern int handle_device_input (Tunnel *tunnel, int fd, int events);
extern int handle_tunnel_input (Tunnel *tunnel, int fd, int events);
extern void name_and_port (const char *nameport, char **name, int *port);
extern int atoi_with_postfix (const char *s_);
extern RETSIGTYPE log_sigpipe (int);
void dump_buf (FILE *f, unsigned char *buf, size_t len);
static inline ssize_t
read_all (int fd, void *buf, size_t len)
{
ssize_t n, m, r;
long flags;
char *rbuf = buf;
flags = fcntl (fd, F_GETFL);
fcntl (fd, F_SETFL, flags & ~O_NONBLOCK);
r = len;
for (n = 0; n < len; n += m)
{
log_annoying ("read (%d, %p, %d) ...", fd, rbuf + n, len - n);
m = read (fd, rbuf + n, len - n);
log_annoying ("... = %d", m);
if (m == 0)
{
r = 0;
break;
}
else if (m == -1)
{
if (errno != EAGAIN)
{
r = -1;
break;
}
else
m = 0;
}
}
fcntl (fd, F_SETFL, flags);
return r;
}
static inline ssize_t
write_all (int fd, void *data, size_t len)
{
ssize_t n, m;
char *wdata = data;
for (n = 0; n < len; n += m)
{
log_annoying ("write (%d, %p, %d) ...", fd, wdata + n, len - n);
m = write (fd, wdata + n, len - n);
log_annoying ("... = %d", m);
if (m == 0)
return 0;
else if (m == -1)
{
if (errno != EAGAIN)
return -1;
else
m = 0;
}
}
return len;
}
static inline int
do_connect (struct sockaddr_in *address)
{
int fd;
fd = socket (AF_INET, SOCK_STREAM, 0);
if (fd == -1)
return -1;
if (connect (fd, (struct sockaddr *)address,
sizeof (struct sockaddr_in)) == -1)
{
close (fd);
return -1;
}
return fd;
}
static inline void
handle_input (const char *type, Tunnel *tunnel, int fd, int events,
int (*handler)(Tunnel *tunnel, int fd, int events),
int *closed)
{
if (events)
{
ssize_t n;
n = handler (tunnel, fd, events);
if (n == 0 || (n == -1 && errno != EAGAIN))
{
if (n == 0)
log_debug ("%s closed", type);
else
log_error ("%s read error: %s", type, strerror (errno));
*closed = TRUE;
}
}
}
#endif /* COMMON_H */