9 #include <sys/socket.h>
16 struct utcp_connection *c;
22 ssize_t 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 ssize_t 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))
87 struct utcp *u = utcp_init(server ? do_accept : NULL, NULL, do_send, &s);
91 utcp_set_mtu(u, 1300);
92 utcp_set_user_timeout(u, 10);
95 c = utcp_connect(u, 1, do_recv, NULL);
97 struct pollfd fds[2] = {
98 {.fd = 0, .events = POLLIN | POLLERR | POLLHUP},
99 {.fd = s, .events = POLLIN | POLLERR | POLLHUP},
103 int timeout = utcp_timeout(u);
106 poll(fds, 2, timeout);
109 int len = read(0, buf, sizeof buf);
114 utcp_shutdown(c, SHUT_WR);
121 utcp_send(c, buf, len);
125 struct sockaddr_storage ss;
126 socklen_t sl = sizeof ss;
127 int len = recvfrom(s, buf, sizeof buf, MSG_DONTWAIT, (struct sockaddr *)&ss, &sl);
131 if(!connect(s, (struct sockaddr *)&ss, sl))
133 if(drand48() >= dropin)
134 utcp_recv(u, buf, len);
137 timeout = utcp_timeout(u);