9 #include <sys/socket.h>
16 struct utcp_connection *c;
22 int do_recv(struct utcp_connection *c, const void *data, size_t len) {
25 fprintf(stderr, "Error: %s\n", strerror(errno));
29 fprintf(stderr, "Connection closed by peer\n");
33 return write(1, data, len);
36 void do_accept(struct utcp_connection *nc, uint16_t port) {
37 utcp_accept(nc, do_recv, NULL);
41 int do_send(struct utcp *utcp, const void *data, size_t len) {
42 int s = *(int *)utcp->priv;
43 if(drand48() >= dropout)
44 return send(s, data, len, MSG_DONTWAIT);
49 int main(int argc, char *argv[]) {
53 if(argc < 2 || argc > 3)
56 bool server = argc == 2;
57 bool connected = false;
59 dropin = atof(getenv("DROPIN") ?: "0");
60 dropout = atof(getenv("DROPOUT") ?: "0");
63 struct addrinfo hint = {
64 .ai_flags = server ? AI_PASSIVE : 0,
65 .ai_socktype = SOCK_DGRAM,
68 getaddrinfo(server ? NULL : argv[1], server ? argv[1] : argv[2], &hint, &ai);
72 int s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
77 if(bind(s, ai->ai_addr, ai->ai_addrlen))
80 if(connect(s, ai->ai_addr, ai->ai_addrlen))
85 struct utcp *u = utcp_init(server ? do_accept : NULL, NULL, do_send, &s);
89 utcp_set_connection_timeout(u, 10);
92 c = utcp_connect(u, 1, do_recv, NULL);
94 struct pollfd fds[2] = {
95 {.fd = 0, .events = POLLIN | POLLERR | POLLHUP},
96 {.fd = s, .events = POLLIN | POLLERR | POLLHUP},
100 int timeout = utcp_timeout(u);
103 poll(fds, 2, timeout);
106 int len = read(0, buf, sizeof buf);
111 utcp_shutdown(c, SHUT_WR);
118 utcp_send(c, buf, len);
122 struct sockaddr_storage ss;
124 int len = recvfrom(s, buf, sizeof buf, MSG_DONTWAIT, (struct sockaddr *)&ss, &sl);
128 if(!connect(s, (struct sockaddr *)&ss, sl))
130 if(drand48() >= dropin)
131 utcp_recv(u, buf, len);
134 timeout = utcp_timeout(u);