1 /*
2 * Project: udptunnel
3 * File: client.h
4 *
5 * Copyright (C) 2009 Daniel Meekins
6 * Contact: dmeekins - gmail
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 3 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 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #ifndef CLIENT_H
23 #define CLIENT_H
24
25 #ifndef WIN32
26 #include <inttypes.h>
27 #include <sys/time.h>
28 #endif /*WIN32*/
29
30 #include "common.h"
31 #include "socket.h"
32 #include "message.h"
33
34 #define CLIENT_TIMEOUT 1 /* in seconds */
35 #define CLIENT_MAX_RESEND 10
36
37 #define CLIENT_WAIT_HELLO 1
38 #define CLIENT_WAIT_DATA0 2
39 #define CLIENT_WAIT_DATA1 3
40 #define CLIENT_WAIT_ACK0 4
41 #define CLIENT_WAIT_ACK1 5
42
43 typedef struct client
44 {
45 uint16_t id; /* Must be first in struct */
46 socket_t *tcp_sock; /* Socket for connection to TCP server */
47 socket_t *udp_sock; /* Socket to hold address from UDP client */
48 int connected;
49 struct timeval keepalive;
50
51 /* For data going from UDP tunnel to TCP connection */
52 char udp2tcp[MSG_MAX_LEN];
53 int udp2tcp_len;
54 int udp2tcp_state;
55
56 /* For data going from TCP connection to UDP tunnel */
57 char tcp2udp[MSG_MAX_LEN];
58 int tcp2udp_len;
59 int tcp2udp_state;
60 struct timeval tcp2udp_timeout;
61 int resend_count;
62 } client_t;
63
64 #define CLIENT_ID(c) ((c)->id)
65
66 client_t *client_create(uint16_t id, socket_t *tcp_sock, socket_t *udp_sock,
67 int connected);
68 client_t *client_copy(client_t *dst, client_t *src, size_t len);
69 int client_cmp(client_t *c1, client_t *c2, size_t len);
70 int client_connect_tcp(client_t *c, char *port);
71 void client_disconnect_tcp(client_t *c);
72 void client_disconnect_udp(client_t *c);
73 void client_free(client_t *c);
74 int client_recv_udp_msg(client_t *client, char *data, int data_len,
75 uint16_t *id, uint8_t *msg_type, uint16_t *len);
76 int client_got_udp_data(client_t *client, char *data, int data_len,
77 uint8_t msg_type);
78 int client_send_tcp_data(client_t *client);
79 int client_recv_tcp_data(client_t *client);
80 int client_send_udp_data(client_t *client);
81 int client_got_ack(client_t *client, uint8_t ack_type);
82 int client_send_hello(client_t *client, char *host, char *port,
83 uint16_t req_id);
84 int client_send_helloack(client_t *client, uint16_t req_id);
85 int client_got_helloack(client_t *client);
86 int client_send_goodbye(client_t *client);
87 int client_check_and_resend(client_t *client, struct timeval curr_tv);
88 int client_check_and_send_keepalive(client_t *client, struct timeval curr_tv);
89 void client_reset_keepalive(client_t *client);
90 int client_timed_out(client_t *client, struct timeval curr_tv);
91
92 /* Function pointers to use when making a list_t of clients */
93 #define p_client_copy ((void* (*)(void *, const void *, size_t))&client_copy)
94 #define p_client_cmp ((int (*)(const void *, const void *, size_t))&client_cmp)
95 #define p_client_free ((void (*)(void *))&client_free)
96
97 /* Inline functions as wrappers for handling the file descriptors in the
98 * client's sockets */
99
client_add_tcp_fd_to_set(client_t * c,fd_set * set)100 static _inline_ void client_add_tcp_fd_to_set(client_t *c, fd_set *set)
101 {
102 if(SOCK_FD(c->tcp_sock) >= 0)
103 FD_SET(SOCK_FD(c->tcp_sock), set);
104 }
105
client_add_udp_fd_to_set(client_t * c,fd_set * set)106 static _inline_ void client_add_udp_fd_to_set(client_t *c, fd_set *set)
107 {
108 if(SOCK_FD(c->udp_sock) >= 0)
109 FD_SET(SOCK_FD(c->udp_sock), set);
110 }
111
client_tcp_fd_isset(client_t * c,fd_set * set)112 static _inline_ int client_tcp_fd_isset(client_t *c, fd_set *set)
113 {
114 return SOCK_FD(c->tcp_sock) >= 0 ?
115 FD_ISSET(SOCK_FD(c->tcp_sock), set) : 0;
116 }
117
client_udp_fd_isset(client_t * c,fd_set * set)118 static _inline_ int client_udp_fd_isset(client_t *c, fd_set *set)
119 {
120 return SOCK_FD(c->udp_sock) >= 0 ?
121 FD_ISSET(SOCK_FD(c->udp_sock), set) : 0;
122
123 }
124
client_remove_tcp_fd_from_set(client_t * c,fd_set * set)125 static _inline_ void client_remove_tcp_fd_from_set(client_t *c, fd_set *set)
126 {
127 if(SOCK_FD(c->tcp_sock) >= 0)
128 FD_CLR(SOCK_FD(c->tcp_sock), set);
129 }
130
client_remove_udp_fd_from_set(client_t * c,fd_set * set)131 static _inline_ void client_remove_udp_fd_from_set(client_t *c, fd_set *set)
132 {
133 if(SOCK_FD(c->udp_sock) >= 0)
134 FD_CLR(SOCK_FD(c->udp_sock), set);
135 }
136
137 #endif /* CLIENT_H */
138