+ struct addrinfo* r = res;
+ udp_socket_t* prev_sock = NULL;
+ while(r) {
+ udp_socket_t* new_sock = malloc(sizeof(udp_socket_t));
+ if(!new_sock) {
+ log_printf(ERROR, "memory error at udp_init");
+ freeaddrinfo(res);
+ udp_close(sock);
+ return -2;
+ }
+ memset(&(new_sock->local_end_), 0, sizeof(new_sock->local_end_));
+ new_sock->next_ = NULL;
+
+ if(!sock->socks_) {
+ sock->socks_ = new_sock;
+ prev_sock = new_sock;
+ }
+ else {
+ prev_sock->next_ = new_sock;
+ prev_sock = new_sock;
+ }
+
+ memcpy(&(new_sock->local_end_), r->ai_addr, r->ai_addrlen);
+ new_sock->fd_ = socket(r->ai_family, SOCK_DGRAM, 0);
+ if(new_sock->fd_ < 0) {
+ log_printf(ERROR, "Error on opening udp socket: %s", strerror(errno));
+ freeaddrinfo(res);
+ udp_close(sock);
+ return -1;
+ }
+
+ if(r->ai_family == AF_INET6) {
+ int on = 1;
+ if(setsockopt(new_sock->fd_, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)))
+ log_printf(ERROR, "Error on setting IPV6_V6ONLY socket option: %s", strerror(errno));
+ }
+
+ errcode = bind(new_sock->fd_, r->ai_addr, r->ai_addrlen);
+ if(errcode) {
+ log_printf(ERROR, "Error on binding udp socket: %s", strerror(errno));
+ freeaddrinfo(res);
+ udp_close(sock);
+ return -1;
+ }
+
+ char* local_string = udp_endpoint_to_string(new_sock->local_end_);
+ if(local_string) {
+ log_printf(NOTICE, "listening on: %s", local_string);
+ free(local_string);
+ }