2 UDP proxy code for connecting two UDP endpoints
3 Released under GNU GPLv3
4 Author: Andrew Tridgell
14 #include <sys/socket.h>
19 #include <sys/types.h>
21 #include <arpa/inet.h>
22 #include <netinet/in.h>
25 static int listen_port1
, listen_port2
;
27 static double timestamp()
30 gettimeofday(&tval
,NULL
);
31 return tval
.tv_sec
+ (tval
.tv_usec
*1.0e-6);
35 open a socket of the specified type, port and address for incoming data
37 int open_socket_in(int port
)
39 struct sockaddr_in sock
;
43 memset(&sock
,0,sizeof(sock
));
45 #ifdef HAVE_SOCK_SIN_LEN
46 sock
.sin_len
= sizeof(sock
);
48 sock
.sin_port
= htons(port
);
49 sock
.sin_family
= AF_INET
;
51 res
= socket(AF_INET
, SOCK_DGRAM
, 0);
53 fprintf(stderr
, "socket failed\n"); return -1;
57 setsockopt(res
,SOL_SOCKET
,SO_REUSEADDR
,(char *)&one
,sizeof(one
));
59 if (bind(res
, (struct sockaddr
*)&sock
, sizeof(sock
)) < 0) {
66 static void main_loop(int sock1
, int sock2
)
68 unsigned char buf
[10240];
69 bool have_conn1
=false;
70 bool have_conn2
=false;
73 int fdmax
= (sock1
>sock2
?sock1
:sock2
)+1;
74 double last_stats
= timestamp();
82 double now
= timestamp();
84 if (verbose
&& now
- last_stats
> 1) {
85 double dt
= now
- last_stats
;
86 printf("%u: %u bytes/sec %u: %u bytes/sec\n",
87 (unsigned)listen_port1
, (unsigned)(bytes_in1
/dt
),
88 (unsigned)listen_port2
, (unsigned)(bytes_in2
/dt
));
89 bytes_in1
= bytes_in2
= 0;
93 if (have_conn1
&& now
- last_pkt1
> 10) {
96 if (have_conn2
&& now
- last_pkt2
> 10) {
107 ret
= select(fdmax
, &fds
, NULL
, NULL
, &tval
);
108 if (ret
== -1 && errno
== EINTR
) continue;
113 if (FD_ISSET(sock1
, &fds
)) {
114 struct sockaddr_in from
;
115 socklen_t fromlen
= sizeof(from
);
116 int n
= recvfrom(sock1
, buf
, sizeof(buf
), 0,
117 (struct sockaddr
*)&from
, &fromlen
);
124 if (connect(sock1
, (struct sockaddr
*)&from
, fromlen
) != 0) {
128 printf("have conn1\n");
131 if (send(sock2
, buf
, n
, 0) != n
) {
137 if (FD_ISSET(sock2
, &fds
)) {
138 struct sockaddr_in from
;
139 socklen_t fromlen
= sizeof(from
);
140 int n
= recvfrom(sock2
, buf
, sizeof(buf
), 0,
141 (struct sockaddr
*)&from
, &fromlen
);
148 if (connect(sock2
, (struct sockaddr
*)&from
, fromlen
) != 0) {
152 printf("have conn2\n");
155 if (send(sock1
, buf
, n
, 0) != n
) {
163 int main(int argc
, char *argv
[])
165 int sock_in1
, sock_in2
;
168 printf("Usage: udpproxy <port1> <port2>\n");
172 verbose
= strcmp(argv
[3],"-v") == 0;
173 printf("verbose=%u\n", (unsigned)verbose
);
177 listen_port1
= atoi(argv
[1]);
178 listen_port2
= atoi(argv
[2]);
180 printf("Opening sockets %u %u\n", listen_port1
, listen_port2
);
181 sock_in1
= open_socket_in(listen_port1
);
182 sock_in2
= open_socket_in(listen_port2
);
183 if (sock_in1
== -1 || sock_in2
== -1) {
184 fprintf(stderr
,"sock on ports %d or %d failed - %s\n",
185 listen_port1
, listen_port2
, strerror(errno
));
189 main_loop(sock_in1
, sock_in2
);