Miniupnpd: update from 1.8 (20140422) to 1.9 (20141209)
[tomato.git] / release / src / router / miniupnpd / testasyncsendto.c
blobc283fdd413b24b8afe5e86d35196a8705fed51e9
1 /* $Id: testasyncsendto.c,v 1.3 2014/11/28 17:08:56 nanard Exp $ */
2 /* MiniUPnP project
3 * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
4 * (c) 2006-2014 Thomas Bernard
5 * This software is subject to the conditions detailed
6 * in the LICENCE file provided within the distribution */
8 #include <sys/types.h>
9 #include <sys/socket.h>
10 #include <netinet/in.h>
11 #include <arpa/inet.h>
12 #include <sys/time.h>
13 #include <string.h>
14 #include <unistd.h>
15 #include <syslog.h>
16 #include <errno.h>
18 #include "miniupnpdtypes.h"
19 #include "upnputils.h"
20 #include "asyncsendto.h"
22 struct lan_addr_list lan_addrs;
24 #define DEST_IP "239.255.255.250"
25 #define DEST_PORT 1900
27 ssize_t
28 sendto_schedule(int sockfd, const void *buf, size_t len, int flags,
29 const struct sockaddr *dest_addr, socklen_t addrlen,
30 unsigned int delay)
33 int test(void)
35 int s;
36 ssize_t n;
37 int i;
38 struct sockaddr_in addr;
39 struct sockaddr_in dest_addr;
40 struct timeval next_send;
41 if( (s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
42 syslog(LOG_ERR, "socket(): %m");
43 return 1;
45 set_non_blocking(s);
46 memset(&addr, 0, sizeof(struct sockaddr_in));
47 addr.sin_family = AF_INET;
48 addr.sin_addr.s_addr = INADDR_ANY;
49 if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
50 syslog(LOG_ERR, "bind(): %m");
51 close(s);
52 return 1;
54 memset(&dest_addr, 0, sizeof(struct sockaddr_in));
55 dest_addr.sin_family = AF_INET;
56 dest_addr.sin_addr.s_addr = inet_addr(DEST_IP);
57 dest_addr.sin_port = htons(DEST_PORT);
58 n = sendto_or_schedule(s, "1234", 4, 0,
59 (struct sockaddr *)&dest_addr, sizeof(dest_addr));
60 syslog(LOG_DEBUG, "sendto_or_schedule : %d", (int)n);
61 n = sendto_schedule(s, "1234", 4, 0,
62 (struct sockaddr *)&dest_addr, sizeof(dest_addr),
63 4400);
64 syslog(LOG_DEBUG, "sendto_schedule : %d", (int)n);
65 n = sendto_schedule(s, "1234", 4, 0,
66 (struct sockaddr *)&dest_addr, sizeof(dest_addr),
67 3000);
68 syslog(LOG_DEBUG, "sendto_schedule : %d", (int)n);
69 while ((i = get_next_scheduled_send(&next_send)) > 0) {
70 fd_set writefds;
71 int max_fd;
72 struct timeval timeout;
73 struct timeval now;
74 syslog(LOG_DEBUG, "get_next_scheduled_send : %d next_send=%ld.%06ld",
75 i, (long)next_send.tv_sec, (long)next_send.tv_usec);
76 FD_ZERO(&writefds);
77 max_fd = 0;
78 gettimeofday(&now, NULL);
79 i = get_sendto_fds(&writefds, &max_fd, &now);
80 if(now.tv_sec > next_send.tv_sec ||
81 (now.tv_sec == next_send.tv_sec && now.tv_usec >= next_send.tv_usec)) {
82 if(i > 0) {
83 /* dont wait */
84 timeout.tv_sec = 0;
85 } else {
86 /* wait 10sec :) */
87 timeout.tv_sec = 10;
89 timeout.tv_usec = 0;
90 } else {
91 /* ... */
92 timeout.tv_sec = (next_send.tv_sec - now.tv_sec);
93 timeout.tv_usec = (next_send.tv_usec - now.tv_usec);
94 if(timeout.tv_usec < 0) {
95 timeout.tv_usec += 1000000;
96 timeout.tv_sec--;
99 syslog(LOG_DEBUG, "get_sendto_fds() returned %d", i);
100 syslog(LOG_DEBUG, "select(%d, NULL, xx, NULL, %ld.%06ld)",
101 max_fd, (long)timeout.tv_sec, (long)timeout.tv_usec);
102 i = select(max_fd, NULL, &writefds, NULL, &timeout);
103 if(i < 0) {
104 syslog(LOG_ERR, "select: %m");
105 if(errno != EINTR)
106 break;
107 } else if(try_sendto(&writefds) < 0) {
108 syslog(LOG_ERR, "try_sendto: %m");
109 break;
112 close(s);
113 return 0;
116 int main(int argc, char * * argv)
118 int r;
119 (void)argc;
120 (void)argv;
121 openlog("testasyncsendto", LOG_CONS|LOG_PERROR, LOG_USER);
122 r = test();
123 closelog();
124 return r;