+
+ // Bind Socket to IP
+ if(iostartup->listening || iostartup->use_srcaddr) {
+ if((iostartup->iptype & IODNS_RECORD_AAAA)) {
+ memset(&ip6, 0, sizeof(ip6));
+ if(iostartup->use_srcaddr) {
+ struct sockaddr_in6 *ip6ptr = iostartup->use_srcaddr->address;
+ ip6.sin6_addr = ip6ptr->sin6_addr;
+ } else
+ inet_pton(AF_INET6, "::1", &ip6.sin6_addr);
+ ip6.sin6_family = addr_family;
+ ip6.sin6_port = htons((iostartup->listening ? iostartup->port : 0));
+ opt = bind(sockfd, (struct sockaddr*)&ip6, sizeof(ip6));
+ } else {
+ memset(&ip6, 0, sizeof(ip6));
+ if(iostartup->use_srcaddr) {
+ struct sockaddr_in4 *ip4ptr = iostartup->use_srcaddr->address;
+ ip6.sin6_addr = ip4ptr->sin_addr;
+ } else
+ ip4.sin_addr = INADDR_ANY;
+ ip4.sin_family = addr_family;
+ ip4.sin_port = htons((iostartup->listening ? iostartup->port : 0));
+ opt = bind(sockfd, (struct sockaddr*)&ip4, sizeof(ip4));
+ }
+ if(!opt) {
+ callback_event.type = IOEVENT_BIND_ERROR;
+ goto iohandler_process_iostartup_fail;
+ }
+ }
+
+ iold = calloc(1, sizeof(*iold));
+ iold->fd = sockfd;
+ iold->flags = IOFLAGS_HAVE_IOFD | IOFLAGS_WANT_READ;
+ iold->data.iofd = iofd;
+
+ if(iostartup->listening) {
+ listen(sockfd, 1);
+ iofd->state = IO_LISTENING;
+ } else {
+ connect(sockfd, iostartup->use_dstaddr->address, iostartup->use_dstaddr->addresslen);
+ iofd->state = IO_CONNECTING;
+ }
+
+ iofd->fd.iold = iold;
+ iofd->flags = IOFDFLAGS_HAVE_IOLD;
+
+ iostartup->iofd = NULL;
+ iohandler_remove_iostartup(iostartup);
+ return;
+
+ iohandler_process_iostartup_fail:
+ if(sockfd)
+ close(sockfd);
+ callback_event.iofd = iostartup->iofd;
+ iostartup->iofd->flags |= IOFDFLAGS_FREE_LOCK;
+ iohandler_trigger_event(&callback_event);
+ iostartup->iofd->flags &= ~IOFDFLAGS_FREE_LOCK;
+ if(iostartup->iofd->flags & IOFDFLAGS_WANT_FREE)
+ iohandler_remove_iostartup(iostartup);
+ else
+ iohandler_close(iostartup->iofd);
+}
+
+static IODNS_CALLBACK(iohandler_dns_callback) {
+ struct IODNSQuery *query = event->query;
+ struct IODescriptorStartup *iostartup = query->data;
+ int trigger_dns_fail = 0;
+ iostartup->iodns = NULL;
+
+ switch((iostartup->flags & IOSTARTUP_LOOKUPS)) {
+ case IOSTARTUP_SRCLOOKUP:
+ if(event->type == IODNSEVENT_FAILED) {
+ trigger_dns_fail = 1;