17c478bd9Sstevel@tonic-gate /* 2*9525b14bSRao Shoaib * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 37c478bd9Sstevel@tonic-gate * Copyright (c) 1995-1999 by Internet Software Consortium 47c478bd9Sstevel@tonic-gate * 57c478bd9Sstevel@tonic-gate * Permission to use, copy, modify, and distribute this software for any 67c478bd9Sstevel@tonic-gate * purpose with or without fee is hereby granted, provided that the above 77c478bd9Sstevel@tonic-gate * copyright notice and this permission notice appear in all copies. 87c478bd9Sstevel@tonic-gate * 9*9525b14bSRao Shoaib * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 10*9525b14bSRao Shoaib * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11*9525b14bSRao Shoaib * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 12*9525b14bSRao Shoaib * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13*9525b14bSRao Shoaib * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14*9525b14bSRao Shoaib * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 15*9525b14bSRao Shoaib * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 167c478bd9Sstevel@tonic-gate */ 177c478bd9Sstevel@tonic-gate 187c478bd9Sstevel@tonic-gate /* ev_connects.c - implement asynch connect/accept for the eventlib 197c478bd9Sstevel@tonic-gate * vix 16sep96 [initial] 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate 227c478bd9Sstevel@tonic-gate #if !defined(LINT) && !defined(CODECENTER) 23*9525b14bSRao Shoaib static const char rcsid[] = "$Id: ev_connects.c,v 1.8 2006/03/09 23:57:56 marka Exp $"; 247c478bd9Sstevel@tonic-gate #endif 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* Import. */ 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate #include "port_before.h" 297c478bd9Sstevel@tonic-gate #include "fd_setsize.h" 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate #include <sys/types.h> 327c478bd9Sstevel@tonic-gate #include <sys/socket.h> 337c478bd9Sstevel@tonic-gate #include <sys/ioctl.h> 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate #include <unistd.h> 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate #include <isc/eventlib.h> 387c478bd9Sstevel@tonic-gate #include <isc/assertions.h> 397c478bd9Sstevel@tonic-gate #include "eventlib_p.h" 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate #include "port_after.h" 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate /* Macros. */ 447c478bd9Sstevel@tonic-gate 457c478bd9Sstevel@tonic-gate #define GETXXXNAME(f, s, sa, len) ( \ 467c478bd9Sstevel@tonic-gate (f((s), (&sa), (&len)) >= 0) ? 0 : \ 477c478bd9Sstevel@tonic-gate (errno != EAFNOSUPPORT && errno != EOPNOTSUPP) ? -1 : ( \ 487c478bd9Sstevel@tonic-gate memset(&(sa), 0, sizeof (sa)), \ 497c478bd9Sstevel@tonic-gate (len) = sizeof (sa), \ 507c478bd9Sstevel@tonic-gate (sa).sa_family = AF_UNIX, \ 517c478bd9Sstevel@tonic-gate 0 \ 527c478bd9Sstevel@tonic-gate ) \ 537c478bd9Sstevel@tonic-gate ) 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gate /* Forward. */ 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate static void listener(evContext ctx, void *uap, int fd, int evmask); 587c478bd9Sstevel@tonic-gate static void connector(evContext ctx, void *uap, int fd, int evmask); 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate /* Public. */ 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate int 637c478bd9Sstevel@tonic-gate evListen(evContext opaqueCtx, int fd, int maxconn, 647c478bd9Sstevel@tonic-gate evConnFunc func, void *uap, evConnID *id) 657c478bd9Sstevel@tonic-gate { 667c478bd9Sstevel@tonic-gate evContext_p *ctx = opaqueCtx.opaque; 677c478bd9Sstevel@tonic-gate evConn *new; 687c478bd9Sstevel@tonic-gate int mode; 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate OKNEW(new); 717c478bd9Sstevel@tonic-gate new->flags = EV_CONN_LISTEN; 72*9525b14bSRao Shoaib OKFREE(mode = fcntl(fd, F_GETFL, NULL), new); /*%< side effect: validate fd. */ 737c478bd9Sstevel@tonic-gate /* 747c478bd9Sstevel@tonic-gate * Remember the nonblocking status. We assume that either evSelectFD 757c478bd9Sstevel@tonic-gate * has not been done to this fd, or that if it has then the caller 767c478bd9Sstevel@tonic-gate * will evCancelConn before they evDeselectFD. If our assumptions 777c478bd9Sstevel@tonic-gate * are not met, then we might restore the old nonblocking status 787c478bd9Sstevel@tonic-gate * incorrectly. 797c478bd9Sstevel@tonic-gate */ 807c478bd9Sstevel@tonic-gate if ((mode & PORT_NONBLOCK) == 0) { 817c478bd9Sstevel@tonic-gate #ifdef USE_FIONBIO_IOCTL 827c478bd9Sstevel@tonic-gate int on = 1; 83*9525b14bSRao Shoaib OKFREE(ioctl(fd, FIONBIO, (char *)&on), new); 847c478bd9Sstevel@tonic-gate #else 85*9525b14bSRao Shoaib OKFREE(fcntl(fd, F_SETFL, mode | PORT_NONBLOCK), new); 867c478bd9Sstevel@tonic-gate #endif 877c478bd9Sstevel@tonic-gate new->flags |= EV_CONN_BLOCK; 887c478bd9Sstevel@tonic-gate } 89*9525b14bSRao Shoaib OKFREE(listen(fd, maxconn), new); 907c478bd9Sstevel@tonic-gate if (evSelectFD(opaqueCtx, fd, EV_READ, listener, new, &new->file) < 0){ 917c478bd9Sstevel@tonic-gate int save = errno; 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate FREE(new); 947c478bd9Sstevel@tonic-gate errno = save; 957c478bd9Sstevel@tonic-gate return (-1); 967c478bd9Sstevel@tonic-gate } 977c478bd9Sstevel@tonic-gate new->flags |= EV_CONN_SELECTED; 987c478bd9Sstevel@tonic-gate new->func = func; 997c478bd9Sstevel@tonic-gate new->uap = uap; 1007c478bd9Sstevel@tonic-gate new->fd = fd; 1017c478bd9Sstevel@tonic-gate if (ctx->conns != NULL) 1027c478bd9Sstevel@tonic-gate ctx->conns->prev = new; 1037c478bd9Sstevel@tonic-gate new->prev = NULL; 1047c478bd9Sstevel@tonic-gate new->next = ctx->conns; 1057c478bd9Sstevel@tonic-gate ctx->conns = new; 1067c478bd9Sstevel@tonic-gate if (id) 1077c478bd9Sstevel@tonic-gate id->opaque = new; 1087c478bd9Sstevel@tonic-gate return (0); 1097c478bd9Sstevel@tonic-gate } 1107c478bd9Sstevel@tonic-gate 1117c478bd9Sstevel@tonic-gate int 1127c478bd9Sstevel@tonic-gate evConnect(evContext opaqueCtx, int fd, const void *ra, int ralen, 1137c478bd9Sstevel@tonic-gate evConnFunc func, void *uap, evConnID *id) 1147c478bd9Sstevel@tonic-gate { 1157c478bd9Sstevel@tonic-gate evContext_p *ctx = opaqueCtx.opaque; 1167c478bd9Sstevel@tonic-gate evConn *new; 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate OKNEW(new); 1197c478bd9Sstevel@tonic-gate new->flags = 0; 1207c478bd9Sstevel@tonic-gate /* Do the select() first to get the socket into nonblocking mode. */ 1217c478bd9Sstevel@tonic-gate if (evSelectFD(opaqueCtx, fd, EV_MASK_ALL, 1227c478bd9Sstevel@tonic-gate connector, new, &new->file) < 0) { 1237c478bd9Sstevel@tonic-gate int save = errno; 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate FREE(new); 1267c478bd9Sstevel@tonic-gate errno = save; 1277c478bd9Sstevel@tonic-gate return (-1); 1287c478bd9Sstevel@tonic-gate } 1297c478bd9Sstevel@tonic-gate new->flags |= EV_CONN_SELECTED; 1307c478bd9Sstevel@tonic-gate if (connect(fd, ra, ralen) < 0 && 1317c478bd9Sstevel@tonic-gate errno != EWOULDBLOCK && 1327c478bd9Sstevel@tonic-gate errno != EAGAIN && 1337c478bd9Sstevel@tonic-gate errno != EINPROGRESS) { 1347c478bd9Sstevel@tonic-gate int save = errno; 1357c478bd9Sstevel@tonic-gate 1367c478bd9Sstevel@tonic-gate (void) evDeselectFD(opaqueCtx, new->file); 1377c478bd9Sstevel@tonic-gate FREE(new); 1387c478bd9Sstevel@tonic-gate errno = save; 1397c478bd9Sstevel@tonic-gate return (-1); 1407c478bd9Sstevel@tonic-gate } 1417c478bd9Sstevel@tonic-gate /* No error, or EWOULDBLOCK. select() tells when it's ready. */ 1427c478bd9Sstevel@tonic-gate new->func = func; 1437c478bd9Sstevel@tonic-gate new->uap = uap; 1447c478bd9Sstevel@tonic-gate new->fd = fd; 1457c478bd9Sstevel@tonic-gate if (ctx->conns != NULL) 1467c478bd9Sstevel@tonic-gate ctx->conns->prev = new; 1477c478bd9Sstevel@tonic-gate new->prev = NULL; 1487c478bd9Sstevel@tonic-gate new->next = ctx->conns; 1497c478bd9Sstevel@tonic-gate ctx->conns = new; 1507c478bd9Sstevel@tonic-gate if (id) 1517c478bd9Sstevel@tonic-gate id->opaque = new; 1527c478bd9Sstevel@tonic-gate return (0); 1537c478bd9Sstevel@tonic-gate } 1547c478bd9Sstevel@tonic-gate 1557c478bd9Sstevel@tonic-gate int 1567c478bd9Sstevel@tonic-gate evCancelConn(evContext opaqueCtx, evConnID id) { 1577c478bd9Sstevel@tonic-gate evContext_p *ctx = opaqueCtx.opaque; 1587c478bd9Sstevel@tonic-gate evConn *this = id.opaque; 1597c478bd9Sstevel@tonic-gate evAccept *acc, *nxtacc; 1607c478bd9Sstevel@tonic-gate int mode; 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gate if ((this->flags & EV_CONN_SELECTED) != 0) 1637c478bd9Sstevel@tonic-gate (void) evDeselectFD(opaqueCtx, this->file); 1647c478bd9Sstevel@tonic-gate if ((this->flags & EV_CONN_BLOCK) != 0) { 1657c478bd9Sstevel@tonic-gate mode = fcntl(this->fd, F_GETFL, NULL); 1667c478bd9Sstevel@tonic-gate if (mode == -1) { 1677c478bd9Sstevel@tonic-gate if (errno != EBADF) 1687c478bd9Sstevel@tonic-gate return (-1); 1697c478bd9Sstevel@tonic-gate } else { 1707c478bd9Sstevel@tonic-gate #ifdef USE_FIONBIO_IOCTL 171*9525b14bSRao Shoaib int off = 0; 172*9525b14bSRao Shoaib OK(ioctl(this->fd, FIONBIO, (char *)&off)); 1737c478bd9Sstevel@tonic-gate #else 174*9525b14bSRao Shoaib OK(fcntl(this->fd, F_SETFL, mode & ~PORT_NONBLOCK)); 1757c478bd9Sstevel@tonic-gate #endif 1767c478bd9Sstevel@tonic-gate } 1777c478bd9Sstevel@tonic-gate } 1787c478bd9Sstevel@tonic-gate 1797c478bd9Sstevel@tonic-gate /* Unlink from ctx->conns. */ 1807c478bd9Sstevel@tonic-gate if (this->prev != NULL) 1817c478bd9Sstevel@tonic-gate this->prev->next = this->next; 1827c478bd9Sstevel@tonic-gate else 1837c478bd9Sstevel@tonic-gate ctx->conns = this->next; 1847c478bd9Sstevel@tonic-gate if (this->next != NULL) 1857c478bd9Sstevel@tonic-gate this->next->prev = this->prev; 1867c478bd9Sstevel@tonic-gate 1877c478bd9Sstevel@tonic-gate /* 1887c478bd9Sstevel@tonic-gate * Remove `this' from the ctx->accepts list (zero or more times). 1897c478bd9Sstevel@tonic-gate */ 1907c478bd9Sstevel@tonic-gate for (acc = HEAD(ctx->accepts), nxtacc = NULL; 1917c478bd9Sstevel@tonic-gate acc != NULL; 1927c478bd9Sstevel@tonic-gate acc = nxtacc) 1937c478bd9Sstevel@tonic-gate { 1947c478bd9Sstevel@tonic-gate nxtacc = NEXT(acc, link); 1957c478bd9Sstevel@tonic-gate if (acc->conn == this) { 1967c478bd9Sstevel@tonic-gate UNLINK(ctx->accepts, acc, link); 1977c478bd9Sstevel@tonic-gate close(acc->fd); 1987c478bd9Sstevel@tonic-gate FREE(acc); 1997c478bd9Sstevel@tonic-gate } 2007c478bd9Sstevel@tonic-gate } 2017c478bd9Sstevel@tonic-gate 2027c478bd9Sstevel@tonic-gate /* Wrap up and get out. */ 2037c478bd9Sstevel@tonic-gate FREE(this); 2047c478bd9Sstevel@tonic-gate return (0); 2057c478bd9Sstevel@tonic-gate } 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate int evHold(evContext opaqueCtx, evConnID id) { 2087c478bd9Sstevel@tonic-gate evConn *this = id.opaque; 2097c478bd9Sstevel@tonic-gate 2107c478bd9Sstevel@tonic-gate if ((this->flags & EV_CONN_LISTEN) == 0) { 2117c478bd9Sstevel@tonic-gate errno = EINVAL; 2127c478bd9Sstevel@tonic-gate return (-1); 2137c478bd9Sstevel@tonic-gate } 2147c478bd9Sstevel@tonic-gate if ((this->flags & EV_CONN_SELECTED) == 0) 2157c478bd9Sstevel@tonic-gate return (0); 2167c478bd9Sstevel@tonic-gate this->flags &= ~EV_CONN_SELECTED; 2177c478bd9Sstevel@tonic-gate return (evDeselectFD(opaqueCtx, this->file)); 2187c478bd9Sstevel@tonic-gate } 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate int evUnhold(evContext opaqueCtx, evConnID id) { 2217c478bd9Sstevel@tonic-gate evConn *this = id.opaque; 2227c478bd9Sstevel@tonic-gate int ret; 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate if ((this->flags & EV_CONN_LISTEN) == 0) { 2257c478bd9Sstevel@tonic-gate errno = EINVAL; 2267c478bd9Sstevel@tonic-gate return (-1); 2277c478bd9Sstevel@tonic-gate } 2287c478bd9Sstevel@tonic-gate if ((this->flags & EV_CONN_SELECTED) != 0) 2297c478bd9Sstevel@tonic-gate return (0); 2307c478bd9Sstevel@tonic-gate ret = evSelectFD(opaqueCtx, this->fd, EV_READ, listener, this, 2317c478bd9Sstevel@tonic-gate &this->file); 2327c478bd9Sstevel@tonic-gate if (ret == 0) 2337c478bd9Sstevel@tonic-gate this->flags |= EV_CONN_SELECTED; 2347c478bd9Sstevel@tonic-gate return (ret); 2357c478bd9Sstevel@tonic-gate } 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate int 2387c478bd9Sstevel@tonic-gate evTryAccept(evContext opaqueCtx, evConnID id, int *sys_errno) { 2397c478bd9Sstevel@tonic-gate evContext_p *ctx = opaqueCtx.opaque; 2407c478bd9Sstevel@tonic-gate evConn *conn = id.opaque; 2417c478bd9Sstevel@tonic-gate evAccept *new; 2427c478bd9Sstevel@tonic-gate 2437c478bd9Sstevel@tonic-gate if ((conn->flags & EV_CONN_LISTEN) == 0) { 2447c478bd9Sstevel@tonic-gate errno = EINVAL; 2457c478bd9Sstevel@tonic-gate return (-1); 2467c478bd9Sstevel@tonic-gate } 2477c478bd9Sstevel@tonic-gate OKNEW(new); 2487c478bd9Sstevel@tonic-gate new->conn = conn; 2497c478bd9Sstevel@tonic-gate new->ralen = sizeof new->ra; 2507c478bd9Sstevel@tonic-gate new->fd = accept(conn->fd, &new->ra.sa, &new->ralen); 2517c478bd9Sstevel@tonic-gate if (new->fd > ctx->highestFD) { 2527c478bd9Sstevel@tonic-gate close(new->fd); 2537c478bd9Sstevel@tonic-gate new->fd = -1; 2547c478bd9Sstevel@tonic-gate new->ioErrno = ENOTSOCK; 2557c478bd9Sstevel@tonic-gate } 2567c478bd9Sstevel@tonic-gate if (new->fd >= 0) { 2577c478bd9Sstevel@tonic-gate new->lalen = sizeof new->la; 2587c478bd9Sstevel@tonic-gate if (GETXXXNAME(getsockname, new->fd, new->la.sa, new->lalen) < 0) { 2597c478bd9Sstevel@tonic-gate new->ioErrno = errno; 2607c478bd9Sstevel@tonic-gate (void) close(new->fd); 2617c478bd9Sstevel@tonic-gate new->fd = -1; 2627c478bd9Sstevel@tonic-gate } else 2637c478bd9Sstevel@tonic-gate new->ioErrno = 0; 2647c478bd9Sstevel@tonic-gate } else { 2657c478bd9Sstevel@tonic-gate new->ioErrno = errno; 2667c478bd9Sstevel@tonic-gate if (errno == EAGAIN || errno == EWOULDBLOCK) { 2677c478bd9Sstevel@tonic-gate FREE(new); 2687c478bd9Sstevel@tonic-gate return (-1); 2697c478bd9Sstevel@tonic-gate } 2707c478bd9Sstevel@tonic-gate } 2717c478bd9Sstevel@tonic-gate INIT_LINK(new, link); 2727c478bd9Sstevel@tonic-gate APPEND(ctx->accepts, new, link); 2737c478bd9Sstevel@tonic-gate *sys_errno = new->ioErrno; 2747c478bd9Sstevel@tonic-gate return (0); 2757c478bd9Sstevel@tonic-gate } 2767c478bd9Sstevel@tonic-gate 2777c478bd9Sstevel@tonic-gate /* Private. */ 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate static void 2807c478bd9Sstevel@tonic-gate listener(evContext opaqueCtx, void *uap, int fd, int evmask) { 2817c478bd9Sstevel@tonic-gate evContext_p *ctx = opaqueCtx.opaque; 2827c478bd9Sstevel@tonic-gate evConn *conn = uap; 2837c478bd9Sstevel@tonic-gate union { 2847c478bd9Sstevel@tonic-gate struct sockaddr sa; 2857c478bd9Sstevel@tonic-gate struct sockaddr_in in; 2867c478bd9Sstevel@tonic-gate #ifndef NO_SOCKADDR_UN 2877c478bd9Sstevel@tonic-gate struct sockaddr_un un; 2887c478bd9Sstevel@tonic-gate #endif 2897c478bd9Sstevel@tonic-gate } la, ra; 2907c478bd9Sstevel@tonic-gate int new; 2917c478bd9Sstevel@tonic-gate ISC_SOCKLEN_T lalen = 0, ralen; 2927c478bd9Sstevel@tonic-gate 2937c478bd9Sstevel@tonic-gate REQUIRE((evmask & EV_READ) != 0); 2947c478bd9Sstevel@tonic-gate ralen = sizeof ra; 2957c478bd9Sstevel@tonic-gate new = accept(fd, &ra.sa, &ralen); 2967c478bd9Sstevel@tonic-gate if (new > ctx->highestFD) { 2977c478bd9Sstevel@tonic-gate close(new); 2987c478bd9Sstevel@tonic-gate new = -1; 2997c478bd9Sstevel@tonic-gate errno = ENOTSOCK; 3007c478bd9Sstevel@tonic-gate } 3017c478bd9Sstevel@tonic-gate if (new >= 0) { 3027c478bd9Sstevel@tonic-gate lalen = sizeof la; 3037c478bd9Sstevel@tonic-gate if (GETXXXNAME(getsockname, new, la.sa, lalen) < 0) { 3047c478bd9Sstevel@tonic-gate int save = errno; 3057c478bd9Sstevel@tonic-gate 3067c478bd9Sstevel@tonic-gate (void) close(new); 3077c478bd9Sstevel@tonic-gate errno = save; 3087c478bd9Sstevel@tonic-gate new = -1; 3097c478bd9Sstevel@tonic-gate } 3107c478bd9Sstevel@tonic-gate } else if (errno == EAGAIN || errno == EWOULDBLOCK) 3117c478bd9Sstevel@tonic-gate return; 3127c478bd9Sstevel@tonic-gate (*conn->func)(opaqueCtx, conn->uap, new, &la.sa, lalen, &ra.sa, ralen); 3137c478bd9Sstevel@tonic-gate } 3147c478bd9Sstevel@tonic-gate 3157c478bd9Sstevel@tonic-gate static void 3167c478bd9Sstevel@tonic-gate connector(evContext opaqueCtx, void *uap, int fd, int evmask) { 3177c478bd9Sstevel@tonic-gate evConn *conn = uap; 3187c478bd9Sstevel@tonic-gate union { 3197c478bd9Sstevel@tonic-gate struct sockaddr sa; 3207c478bd9Sstevel@tonic-gate struct sockaddr_in in; 3217c478bd9Sstevel@tonic-gate #ifndef NO_SOCKADDR_UN 3227c478bd9Sstevel@tonic-gate struct sockaddr_un un; 3237c478bd9Sstevel@tonic-gate #endif 3247c478bd9Sstevel@tonic-gate } la, ra; 3257c478bd9Sstevel@tonic-gate ISC_SOCKLEN_T lalen, ralen; 326*9525b14bSRao Shoaib #ifndef NETREAD_BROKEN 3277c478bd9Sstevel@tonic-gate char buf[1]; 328*9525b14bSRao Shoaib #endif 3297c478bd9Sstevel@tonic-gate void *conn_uap; 3307c478bd9Sstevel@tonic-gate evConnFunc conn_func; 3317c478bd9Sstevel@tonic-gate evConnID id; 3327c478bd9Sstevel@tonic-gate int socket_errno = 0; 3337c478bd9Sstevel@tonic-gate ISC_SOCKLEN_T optlen; 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate UNUSED(evmask); 3367c478bd9Sstevel@tonic-gate 3377c478bd9Sstevel@tonic-gate lalen = sizeof la; 3387c478bd9Sstevel@tonic-gate ralen = sizeof ra; 3397c478bd9Sstevel@tonic-gate conn_uap = conn->uap; 3407c478bd9Sstevel@tonic-gate conn_func = conn->func; 3417c478bd9Sstevel@tonic-gate id.opaque = conn; 3427c478bd9Sstevel@tonic-gate #ifdef SO_ERROR 3437c478bd9Sstevel@tonic-gate optlen = sizeof socket_errno; 3447c478bd9Sstevel@tonic-gate if (fd < 0 && 3457c478bd9Sstevel@tonic-gate getsockopt(conn->fd, SOL_SOCKET, SO_ERROR, (char *)&socket_errno, 3467c478bd9Sstevel@tonic-gate &optlen) < 0) 3477c478bd9Sstevel@tonic-gate socket_errno = errno; 3487c478bd9Sstevel@tonic-gate else 3497c478bd9Sstevel@tonic-gate errno = socket_errno; 3507c478bd9Sstevel@tonic-gate #endif 3517c478bd9Sstevel@tonic-gate if (evCancelConn(opaqueCtx, id) < 0 || 3527c478bd9Sstevel@tonic-gate socket_errno || 3537c478bd9Sstevel@tonic-gate #ifdef NETREAD_BROKEN 3547c478bd9Sstevel@tonic-gate 0 || 3557c478bd9Sstevel@tonic-gate #else 3567c478bd9Sstevel@tonic-gate read(fd, buf, 0) < 0 || 3577c478bd9Sstevel@tonic-gate #endif 3587c478bd9Sstevel@tonic-gate GETXXXNAME(getsockname, fd, la.sa, lalen) < 0 || 3597c478bd9Sstevel@tonic-gate GETXXXNAME(getpeername, fd, ra.sa, ralen) < 0) { 3607c478bd9Sstevel@tonic-gate int save = errno; 3617c478bd9Sstevel@tonic-gate 362*9525b14bSRao Shoaib (void) close(fd); /*%< XXX closing caller's fd */ 3637c478bd9Sstevel@tonic-gate errno = save; 3647c478bd9Sstevel@tonic-gate fd = -1; 3657c478bd9Sstevel@tonic-gate } 3667c478bd9Sstevel@tonic-gate (*conn_func)(opaqueCtx, conn_uap, fd, &la.sa, lalen, &ra.sa, ralen); 3677c478bd9Sstevel@tonic-gate } 368*9525b14bSRao Shoaib 369*9525b14bSRao Shoaib /*! \file */ 370