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