int udp_listener_init(struct udp_listener *u, struct poller *p, const endpoint_t *ep, udp_listener_callback_t func, struct obj *obj) { struct poller_item i; struct udp_listener_callback *cb; cb = obj_alloc("udp_listener_callback", sizeof(*cb), NULL); cb->func = func; cb->p = obj_get_o(obj); cb->ul = u; if (open_socket(&u->sock, SOCK_DGRAM, ep->port, &ep->address)) goto fail; ipv6only(u->sock.fd, 1); ZERO(i); i.fd = u->sock.fd; i.closed = udp_listener_closed; i.readable = udp_listener_incoming; i.obj = &cb->obj; if (poller_add_item(p, &i)) goto fail; return 0; fail: close_socket(&u->sock); obj_put_o(obj); obj_put(cb); return -1; }
int udp_listener_init(struct udp_listener *u, struct poller *p, struct in6_addr ip, u_int16_t port, udp_listener_callback_t func, struct obj *obj) { struct sockaddr_in6 sin; struct poller_item i; struct udp_listener_callback *cb; cb = obj_alloc("udp_listener_callback", sizeof(*cb), NULL); cb->func = func; cb->p = obj_get_o(obj); u->fd = socket(AF_INET6, SOCK_DGRAM, 0); if (u->fd == -1) goto fail; nonblock(u->fd); reuseaddr(u->fd); ipv6only(u->fd, 0); ZERO(sin); sin.sin6_family = AF_INET6; sin.sin6_addr = ip; sin.sin6_port = htons(port); if (bind(u->fd, (struct sockaddr *) &sin, sizeof(sin))) goto fail; ZERO(i); i.fd = u->fd; i.closed = udp_listener_closed; i.readable = udp_listener_incoming; i.obj = &cb->obj; if (poller_add_item(p, &i)) goto fail; return 0; fail: if (u->fd != -1) close(u->fd); obj_put_o(obj); obj_put(cb); return -1; }