/* alloc */
n = (struct listen_port*)calloc(1, sizeof(*n));
if(!n) {
+#ifndef USE_WINSOCK
close(fd);
+#else
+ closesocket(fd);
+#endif
log_err("out of memory");
return 0;
}
if(rc->active >= rc->max_active) {
log_warn("drop incoming remote control: too many connections");
comm_point_stop_listening(c);
+ close_exit:
+#ifndef USE_WINSOCK
close(newfd);
+#else
+ closesocket(newfd);
+#endif
return 0;
}
n = (struct rc_state*)calloc(1, sizeof(*n));
if(!n) {
log_err("out of memory");
- close(newfd);
- return 0;
+ goto close_exit;
}
/* start in reading state */
n->c = comm_point_create_raw(rc->worker->base, newfd, 0,
&remote_control_callback, n);
if(!n->c) {
log_err("out of memory");
- close(newfd);
free(n);
- return 0;
+ goto close_exit;
}
log_addr(VERB_QUERY, "new control connection from", &addr, addrlen);
n->c->do_not_close = 0;
n->ssl = SSL_new(rc->ctx);
if(!n->ssl) {
log_crypto_err("could not SSL_new");
- close(newfd);
free(n);
- return 0;
+ goto close_exit;
}
SSL_set_accept_state(n->ssl);
(void)SSL_set_mode(n->ssl, SSL_MODE_AUTO_RETRY);
if(!SSL_set_fd(n->ssl, newfd)) {
log_crypto_err("could not SSL_set_fd");
- close(newfd);
SSL_free(n->ssl);
free(n);
- return 0;
+ goto close_exit;
}
n->rc = rc;
Ondřej Surý - running coverity analysis tool on 0.9 dev version.
Alexander Gall - multihomed, anycast testing of unbound resolver server.
Zdenek Vasicek and Marek Vavrusa - python module.
+Brett Carr - windows beta testing.
+29 April 2009: Wouter
+ - Thanks to Brett Carr, caught windows resource leak, use
+ closesocket() and not close() on sockets or else the network stack
+ starts to leak handles.
+ - Removed usage of windows Mutex because windows cannot handle enough
+ mutexes open. Provide own mutex implementation using primitives.
+
28 April 2009: Wouter
- created svn tag for 1.3.0.
#ifndef USE_WINSOCK
log_err("setsockopt(..., IPV6_V6ONLY"
", ...) failed: %s", strerror(errno));
+ close(s);
#else
log_err("setsockopt(..., IPV6_V6ONLY"
", ...) failed: %s",
wsa_strerror(WSAGetLastError()));
+ closesocket(s);
#endif
- close(s);
*noproto = 0;
*inuse = 0;
return -1;
#ifndef USE_WINSOCK
log_err("setsockopt(..., IPV6_USE_MIN_MTU, "
"...) failed: %s", strerror(errno));
+ close(s);
#else
log_err("setsockopt(..., IPV6_USE_MIN_MTU, "
"...) failed: %s",
wsa_strerror(WSAGetLastError()));
+ closesocket(s);
#endif
- close(s);
*noproto = 0;
*inuse = 0;
return -1;
else if(errno != EADDRINUSE)
log_err("can't bind socket: %s", strerror(errno));
#endif
+ close(s);
#else /* USE_WINSOCK */
if(WSAGetLastError() != WSAEADDRINUSE &&
WSAGetLastError() != WSAEADDRNOTAVAIL)
log_err("can't bind socket: %s",
wsa_strerror(WSAGetLastError()));
+ closesocket(s);
#endif
- close(s);
return -1;
}
if(!fd_set_nonblock(s)) {
*noproto = 0;
*inuse = 0;
+#ifndef USE_WINSOCK
close(s);
+#else
+ closesocket(s);
+#endif
return -1;
}
return s;
if(!set_recvpktinfo(s, hints->ai_family))
return 0;
if(!port_insert(list, s, listen_type_udpancil)) {
+#ifndef USE_WINSOCK
close(s);
+#else
+ closesocket(s);
+#endif
return 0;
}
} else if(do_udp) {
return 0;
}
if(!port_insert(list, s, listen_type_udp)) {
+#ifndef USE_WINSOCK
close(s);
+#else
+ closesocket(s);
+#endif
return 0;
}
}
return 0;
}
if(!port_insert(list, s, listen_type_tcp)) {
+#ifndef USE_WINSOCK
close(s);
+#else
+ closesocket(s);
+#endif
return 0;
}
}
struct listen_port* nx;
while(list) {
nx = list->next;
- if(list->fd != -1)
+ if(list->fd != -1) {
+#ifndef USE_WINSOCK
close(list->fd);
+#else
+ closesocket(list->fd);
+#endif
+ }
free(list);
list = nx;
}
if(1) {
#endif
log_err("outgoing tcp: connect: %s", strerror(errno));
+ close(s);
#else /* USE_WINSOCK */
if(WSAGetLastError() != WSAEINPROGRESS &&
WSAGetLastError() != WSAEWOULDBLOCK) {
+ closesocket(s);
#endif
log_addr(0, "failed address", &w->addr, w->addrlen);
- close(s);
return 0;
}
}
ret = go_cmd(ssl, argc, argv);
SSL_free(ssl);
+#ifndef USE_WINSOCK
close(fd);
+#else
+ closesocket(fd);
+#endif
SSL_CTX_free(ctx);
config_delete(cfg);
return ret;
free(s);
s = sn;
}
+#ifndef USE_WINSOCK
close(p->client_s);
if(p->server_s != -1)
close(p->server_s);
+#else
+ closesocket(p->client_s);
+ if(p->server_s != -1)
+ closesocket(p->server_s);
+#endif
free(p);
}
#ifndef USE_WINSOCK
if(errno != EINPROGRESS) {
log_err("tcp connect: %s", strerror(errno));
+ close(p->server_s);
+ close(p->client_s);
#else
if(WSAGetLastError() != WSAEWOULDBLOCK &&
WSAGetLastError() != WSAEINPROGRESS) {
log_err("tcp connect: %s",
wsa_strerror(WSAGetLastError()));
+ closesocket(p->server_s);
+ closesocket(p->client_s);
#endif
- close(p->server_s);
- close(p->client_s);
free(p);
return;
}
log_addr(1, "read tcp answer", &p->addr, p->addr_len);
if(!tcp_relay_read(p->server_s, &p->answerlist,
&p->answerlast, now, delay, pkt)) {
+#ifndef USE_WINSOCK
close(p->server_s);
+#else
+ closesocket(p->server_s);
+#endif
FD_CLR(FD_SET_T p->server_s, worig);
FD_CLR(FD_SET_T p->server_s, rorig);
p->server_s = -1;
"%u returned\n", i++, from, port, (int)p->numreuse+1,
(unsigned)p->numwait, (unsigned)p->numsent,
(unsigned)p->numreturn);
+#ifndef USE_WINSOCK
close(p->s);
+#else
+ closesocket(p->s);
+#endif
free(p);
p = np;
}
/* cleanup */
verbose(1, "cleanup");
+#ifndef USE_WINSOCK
close(s);
close(listen_s);
+#else
+ closesocket(s);
+ closesocket(listen_s);
+#endif
ldns_buffer_free(pkt);
ring_delete(ring);
}
if(!info) return;
if(info->io) {
for(i=0; i<info->io_num; i++) {
+#ifndef USE_WINSOCK
close(info->io[i].fd);
+#else
+ closesocket(info->io[i].fd);
+#endif
}
free(info->io);
}
recv_one(fd, udp, buf);
}
+#ifndef USE_WINSOCK
close(fd);
+#else
+ closesocket(fd);
+#endif
ldns_buffer_free(buf);
printf("orderly exit\n");
}
void lock_basic_init(lock_basic_t* lock)
{
- *lock = CreateMutex(NULL, /* security attrs NULL, not process inherit*/
- 0, /* false, we do not hold the lock initially */
- NULL); /* create anonymous mutex */
- if(*lock == NULL) {
- log_win_err("CreateMutex failed", GetLastError());
- fatal_exit("lock init failed");
- }
+ /* implement own lock, because windows HANDLE as Mutex usage
+ * uses too many handles and would bog down the whole system. */
+ (void)InterlockedExchange(lock, 0);
}
void lock_basic_destroy(lock_basic_t* lock)
{
- if(!CloseHandle(*lock)) {
- log_win_err("CloseHandle(Mutex) failed", GetLastError());
- }
- *lock = NULL;
+ (void)InterlockedExchange(lock, 0);
}
void lock_basic_lock(lock_basic_t* lock)
{
- DWORD ret = WaitForSingleObject(*lock, INFINITE);
- if(ret == WAIT_FAILED) {
- log_win_err("WaitForSingleObject(Mutex):WAIT_FAILED",
- GetLastError());
- } else if(ret == WAIT_TIMEOUT) {
- log_win_err("WaitForSingleObject(Mutex):WAIT_TIMEOUT",
- GetLastError());
+ LONG wait = 1; /* wait 1 msec at first */
+
+ while(InterlockedExchange(lock, 1)) {
+ /* if the old value was 1 then if was already locked */
+ Sleep(wait); /* wait with sleep */
+ wait *= 2; /* exponential backoff for waiting */
}
- /* both WAIT_ABANDONED and WAIT_OBJECT_0 mean we have the lock */
+ /* the old value was 0, but we inserted 1, we locked it! */
}
void lock_basic_unlock(lock_basic_t* lock)
{
- if(!ReleaseMutex(*lock)) {
- log_win_err("ReleaseMutex failed", GetLastError());
- }
+ /* unlock it by inserting the value of 0. xchg for cache coherency. */
+ (void)InterlockedExchange(lock, 0);
}
void ub_thread_key_create(ub_thread_key_t* key, void* f)
#include <windows.h>
/* Use a mutex */
-typedef HANDLE lock_rw_t;
+typedef LONG lock_rw_t;
#define lock_rw_init(lock) lock_basic_init(lock)
#define lock_rw_destroy(lock) lock_basic_destroy(lock)
#define lock_rw_rdlock(lock) lock_basic_lock(lock)
#define lock_rw_unlock(lock) lock_basic_unlock(lock)
/** the basic lock is a mutex, implemented opaquely, for error handling. */
-typedef HANDLE lock_basic_t;
+typedef LONG lock_basic_t;
void lock_basic_init(lock_basic_t* lock);
void lock_basic_destroy(lock_basic_t* lock);
void lock_basic_lock(lock_basic_t* lock);
void lock_basic_unlock(lock_basic_t* lock);
/** on windows no spinlock, use mutex too. */
-typedef HANDLE lock_quick_t;
+typedef LONG lock_quick_t;
#define lock_quick_init(lock) lock_basic_init(lock)
#define lock_quick_destroy(lock) lock_basic_destroy(lock)
#define lock_quick_lock(lock) lock_basic_lock(lock)
/* close fd after removing from event lists, or epoll.. is messed up */
if(c->fd != -1 && !c->do_not_close) {
verbose(VERB_ALGO, "close fd %d", c->fd);
+#ifndef USE_WINSOCK
close(c->fd);
+#else
+ closesocket(c->fd);
+#endif
}
c->fd = -1;
}
else c->ev->ev.ev_events |= EV_WRITE;
}
if(newfd != -1) {
- if(c->fd != -1)
+ if(c->fd != -1) {
+#ifndef USE_WINSOCK
close(c->fd);
+#else
+ closesocket(c->fd);
+#endif
+ }
c->fd = newfd;
c->ev->ev.ev_fd = c->fd;
}