static apr_status_t impl_pollcb_add(apr_pollcb_t *pollcb, apr_pollfd_t *descriptor) { apr_os_sock_t fd; struct kevent ev; apr_status_t rv = APR_SUCCESS; if (descriptor->desc_type == APR_POLL_SOCKET) { fd = descriptor->desc.s->socketdes; } else { fd = descriptor->desc.f->filedes; } if (descriptor->reqevents & APR_POLLIN) { EV_SET(&ev, fd, EVFILT_READ, EV_ADD, 0, 0, descriptor); if (kevent(pollcb->fd, &ev, 1, NULL, 0, NULL) == -1) { rv = apr_get_netos_error(); } } if (descriptor->reqevents & APR_POLLOUT && rv == APR_SUCCESS) { EV_SET(&ev, fd, EVFILT_WRITE, EV_ADD, 0, 0, descriptor); if (kevent(pollcb->fd, &ev, 1, NULL, 0, NULL) == -1) { rv = apr_get_netos_error(); } } return rv; }
static PCOMP_CONTEXT win9x_get_connection(PCOMP_CONTEXT context) { apr_os_sock_info_t sockinfo; int len, salen; #if APR_HAVE_IPV6 salen = sizeof(struct sockaddr_in6); #else salen = sizeof(struct sockaddr_in); #endif if (context == NULL) { /* allocate the completion context and the transaction pool */ apr_allocator_t *allocator; apr_thread_mutex_lock(child_lock); context = apr_pcalloc(pchild, sizeof(COMP_CONTEXT)); apr_allocator_create(&allocator); apr_allocator_max_free_set(allocator, ap_max_mem_free); apr_pool_create_ex(&context->ptrans, pchild, NULL, allocator); apr_allocator_owner_set(allocator, context->ptrans); apr_pool_tag(context->ptrans, "transaction"); apr_thread_mutex_unlock(child_lock); } while (1) { apr_pool_clear(context->ptrans); context->ba = apr_bucket_alloc_create(context->ptrans); context->accept_socket = remove_job(); if (context->accept_socket == INVALID_SOCKET) { return NULL; } len = salen; context->sa_server = apr_palloc(context->ptrans, len); if (getsockname(context->accept_socket, context->sa_server, &len)== SOCKET_ERROR) { ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_netos_error(), ap_server_conf, "getsockname failed"); continue; } len = salen; context->sa_client = apr_palloc(context->ptrans, len); if ((getpeername(context->accept_socket, context->sa_client, &len)) == SOCKET_ERROR) { ap_log_error(APLOG_MARK, APLOG_WARNING, apr_get_netos_error(), ap_server_conf, "getpeername failed"); memset(&context->sa_client, '\0', sizeof(context->sa_client)); } sockinfo.os_sock = &context->accept_socket; sockinfo.local = context->sa_server; sockinfo.remote = context->sa_client; sockinfo.family = context->sa_server->sa_family; sockinfo.type = SOCK_STREAM; apr_os_sock_make(&context->sock, &sockinfo, context->ptrans); return context; } }
static apr_status_t impl_pollset_add(apr_pollset_t *pollset, const apr_pollfd_t *descriptor) { apr_os_sock_t fd; pfd_elem_t *elem; apr_status_t rv = APR_SUCCESS; pollset_lock_rings(); if (!APR_RING_EMPTY(&(pollset->p->free_ring), pfd_elem_t, link)) { elem = APR_RING_FIRST(&(pollset->p->free_ring)); APR_RING_REMOVE(elem, link); } else { elem = (pfd_elem_t *) apr_palloc(pollset->pool, sizeof(pfd_elem_t)); APR_RING_ELEM_INIT(elem, link); } elem->pfd = *descriptor; if (descriptor->desc_type == APR_POLL_SOCKET) { fd = descriptor->desc.s->socketdes; } else { fd = descriptor->desc.f->filedes; } if (descriptor->reqevents & APR_POLLIN) { EV_SET(&pollset->p->kevent, fd, EVFILT_READ, EV_ADD, 0, 0, elem); if (kevent(pollset->p->kqueue_fd, &pollset->p->kevent, 1, NULL, 0, NULL) == -1) { rv = apr_get_netos_error(); } } if (descriptor->reqevents & APR_POLLOUT && rv == APR_SUCCESS) { EV_SET(&pollset->p->kevent, fd, EVFILT_WRITE, EV_ADD, 0, 0, elem); if (kevent(pollset->p->kqueue_fd, &pollset->p->kevent, 1, NULL, 0, NULL) == -1) { rv = apr_get_netos_error(); } } if (rv == APR_SUCCESS) { APR_RING_INSERT_TAIL(&(pollset->p->query_ring), elem, pfd_elem_t, link); } else { APR_RING_INSERT_TAIL(&(pollset->p->free_ring), elem, pfd_elem_t, link); } pollset_unlock_rings(); return rv; }
static apr_status_t impl_pollcb_create(apr_pollcb_t *pollcb, apr_uint32_t size, apr_pool_t *p, apr_uint32_t flags) { int fd; fd = kqueue(); if (fd < 0) { return apr_get_netos_error(); } { int flags; if ((flags = fcntl(fd, F_GETFD)) == -1) return errno; flags |= FD_CLOEXEC; if (fcntl(fd, F_SETFD, flags) == -1) return errno; } pollcb->fd = fd; pollcb->pollset.ke = (struct kevent *)apr_pcalloc(p, 2 * size * sizeof(struct kevent)); apr_pool_cleanup_register(p, pollcb, cb_cleanup, apr_pool_cleanup_null); return APR_SUCCESS; }
static apr_status_t call_port_getn(int port, port_event_t list[], unsigned int max, unsigned int *nget, apr_interval_time_t timeout) { struct timespec tv, *tvptr; int ret; apr_status_t rv = APR_SUCCESS; if (timeout < 0) { tvptr = NULL; } else { tv.tv_sec = (long) apr_time_sec(timeout); tv.tv_nsec = (long) apr_time_usec(timeout) * 1000; tvptr = &tv; } list[0].portev_user = (void *)-1; /* so we can double check that an * event was returned */ ret = port_getn(port, list, max, nget, tvptr); /* Note: 32-bit port_getn() on Solaris 10 x86 returns large negative * values instead of 0 when returning immediately. */ if (ret == -1) { rv = apr_get_netos_error(); switch(rv) { case EINTR: case ETIME: if (*nget > 0 && list[0].portev_user != (void *)-1) { /* This confusing API can return an event at the same time * that it reports EINTR or ETIME. If that occurs, just * report the event. With EINTR, nget can be > 0 without * any event, so check that portev_user was filled in. * * (Maybe it will be simplified; see thread * http://mail.opensolaris.org * /pipermail/networking-discuss/2009-August/011979.html * This code will still work afterwards.) */ rv = APR_SUCCESS; break; } if (rv == ETIME) { rv = APR_TIMEUP; } /* fall-through */ default: *nget = 0; } } else if (*nget == 0) { rv = APR_TIMEUP; } return rv; }
static apr_status_t impl_pollcb_create(apr_pollcb_t *pollcb, apr_uint32_t size, apr_pool_t *p, apr_uint32_t flags) { pollcb->fd = port_create(); if (pollcb->fd < 0) { return apr_get_netos_error(); } { int flags; if ((flags = fcntl(pollcb->fd, F_GETFD)) == -1) return errno; flags |= FD_CLOEXEC; if (fcntl(pollcb->fd, F_SETFD, flags) == -1) return errno; } pollcb->pollset.port = apr_palloc(p, size * sizeof(port_event_t)); apr_pool_cleanup_register(p, pollcb, cb_cleanup, apr_pool_cleanup_null); return APR_SUCCESS; }
APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, apr_interval_time_t timeout, apr_int32_t *num, const apr_pollfd_t **descriptors) { int rv; apr_uint32_t i, j; if (timeout > 0) { timeout /= 1000; } rv = poll(pollset->pollset, pollset->nelts, timeout); (*num) = rv; if (rv < 0) { return apr_get_netos_error(); } if (rv == 0) { return APR_TIMEUP; } j = 0; for (i = 0; i < pollset->nelts; i++) { if (pollset->pollset[i].revents != 0) { pollset->result_set[j] = pollset->query_set[i]; pollset->result_set[j].rtnevents = get_revent(pollset->pollset[i].revents); j++; } } *descriptors = pollset->result_set; return APR_SUCCESS; }
static apr_status_t impl_pollcb_add(apr_pollcb_t *pollcb, apr_pollfd_t *descriptor) { #ifdef HAVE_MTCP struct mtcp_epoll_event ev; #else struct epoll_event ev; #endif int ret; ev.events = get_epoll_event(descriptor->reqevents); ev.data.ptr = (void *)descriptor; if (descriptor->desc_type == APR_POLL_SOCKET) { ret = epoll_ctl(pollcb->fd, EPOLL_CTL_ADD, descriptor->desc.s->socketdes, &ev); } else { ret = epoll_ctl(pollcb->fd, EPOLL_CTL_ADD, descriptor->desc.f->filedes, &ev); } if (ret == -1) { return apr_get_netos_error(); } return APR_SUCCESS; }
APR_DECLARE(apr_status_t) apr_socket_recv(apr_socket_t *sock, char *buf, apr_size_t *len) { apr_ssize_t rv; WSABUF wsaData; int lasterror; DWORD dwBytes = 0; DWORD flags = 0; wsaData.len = (u_long)*len; wsaData.buf = (char*) buf; #ifndef _WIN32_WCE rv = WSARecv(sock->socketdes, &wsaData, 1, &dwBytes, &flags, NULL, NULL); #else rv = recv(sock->socketdes, wsaData.buf, wsaData.len, 0); dwBytes = rv; #endif if (rv == SOCKET_ERROR) { lasterror = apr_get_netos_error(); *len = 0; return lasterror; } *len = dwBytes; return dwBytes == 0 ? APR_EOF : APR_SUCCESS; }
APR_DECLARE(apr_status_t) apr_socket_recvfrom(apr_sockaddr_t *from, apr_socket_t *sock, apr_int32_t flags, char *buf, apr_size_t *len) { apr_ssize_t rv; from->salen = sizeof(from->sa); rv = recvfrom(sock->socketdes, buf, (int)*len, flags, (struct sockaddr*)&from->sa, &from->salen); if (rv == SOCKET_ERROR) { (*len) = 0; return apr_get_netos_error(); } apr_sockaddr_vars_set(from, from->sa.sin.sin_family, ntohs(from->sa.sin.sin_port)); (*len) = rv; if (rv == 0 && sock->type == SOCK_STREAM) return APR_EOF; return APR_SUCCESS; }
static apr_status_t get_canonical_hostname(const char **canonname, const char *hostname, apr_pool_t *pool) { struct addrinfo hints; struct addrinfo *addrinfo; ZeroMemory(&hints, sizeof(hints)); hints.ai_flags = AI_CANONNAME; if (getaddrinfo(hostname, NULL, &hints, &addrinfo)) { return apr_get_netos_error(); } if (addrinfo) { *canonname = apr_pstrdup(pool, addrinfo->ai_canonname); } else { *canonname = apr_pstrdup(pool, hostname); } freeaddrinfo(addrinfo); return APR_SUCCESS; }
static apr_status_t impl_pollcb_poll(apr_pollcb_t *pollcb, apr_interval_time_t timeout, apr_pollcb_cb_t func, void *baton) { int ret, i; apr_status_t rv = APR_SUCCESS; if (timeout > 0) { timeout /= 1000; } ret = epoll_wait(pollcb->fd, pollcb->pollset.epoll, pollcb->nalloc, timeout); if (ret < 0) { rv = apr_get_netos_error(); } else if (ret == 0) { rv = APR_TIMEUP; } else { for (i = 0; i < ret; i++) { apr_pollfd_t *pollfd = (apr_pollfd_t *)(pollcb->pollset.epoll[i].data.ptr); pollfd->rtnevents = get_epoll_revent(pollcb->pollset.epoll[i].events); rv = func(baton, pollfd); if (rv) { return rv; } } } return rv; }
static apr_status_t impl_pollset_create(apr_pollset_t *pollset, apr_uint32_t size, apr_pool_t *p, apr_uint32_t flags) { apr_status_t rv; int fd; #ifdef HAVE_EPOLL_CREATE1 fd = epoll_create1(EPOLL_CLOEXEC); #else fd = epoll_create(size); #endif if (fd < 0) { pollset->p = NULL; return apr_get_netos_error(); } #ifndef HAVE_EPOLL_CREATE1 { int flags; if ((flags = fcntl(fd, F_GETFD)) == -1) return errno; flags |= FD_CLOEXEC; if (fcntl(fd, F_SETFD, flags) == -1) return errno; } #endif pollset->p = apr_palloc(p, sizeof(apr_pollset_private_t)); #if APR_HAS_THREADS if ((flags & APR_POLLSET_THREADSAFE) && !(flags & APR_POLLSET_NOCOPY) && ((rv = apr_thread_mutex_create(&pollset->p->ring_lock, APR_THREAD_MUTEX_DEFAULT, p)) != APR_SUCCESS)) { pollset->p = NULL; return rv; } #else if (flags & APR_POLLSET_THREADSAFE) { pollset->p = NULL; return APR_ENOTIMPL; } #endif pollset->p->epoll_fd = fd; pollset->p->pollset = apr_palloc(p, size * sizeof(struct epoll_event)); pollset->p->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t)); if (!(flags & APR_POLLSET_NOCOPY)) { APR_RING_INIT(&pollset->p->query_ring, pfd_elem_t, link); APR_RING_INIT(&pollset->p->free_ring, pfd_elem_t, link); APR_RING_INIT(&pollset->p->dead_ring, pfd_elem_t, link); } return APR_SUCCESS; }
static apr_status_t impl_pollset_add(apr_pollset_t *pollset, const apr_pollfd_t *descriptor) { apr_os_sock_t fd; pfd_elem_t *elem; int res; apr_status_t rv = APR_SUCCESS; pollset_lock_rings(); if (!APR_RING_EMPTY(&(pollset->p->free_ring), pfd_elem_t, link)) { elem = APR_RING_FIRST(&(pollset->p->free_ring)); APR_RING_REMOVE(elem, link); } else { elem = (pfd_elem_t *) apr_palloc(pollset->pool, sizeof(pfd_elem_t)); APR_RING_ELEM_INIT(elem, link); elem->on_query_ring = 0; } elem->pfd = *descriptor; if (descriptor->desc_type == APR_POLL_SOCKET) { fd = descriptor->desc.s->socketdes; } else { fd = descriptor->desc.f->filedes; } /* If another thread is polling, notify the kernel immediately; otherwise, * wait until the next call to apr_pollset_poll(). */ if (apr_atomic_read32(&pollset->p->waiting)) { res = port_associate(pollset->p->port_fd, PORT_SOURCE_FD, fd, get_event(descriptor->reqevents), (void *)elem); if (res < 0) { rv = apr_get_netos_error(); APR_RING_INSERT_TAIL(&(pollset->p->free_ring), elem, pfd_elem_t, link); } else { elem->on_query_ring = 1; APR_RING_INSERT_TAIL(&(pollset->p->query_ring), elem, pfd_elem_t, link); } } else { APR_RING_INSERT_TAIL(&(pollset->p->add_ring), elem, pfd_elem_t, link); } pollset_unlock_rings(); return rv; }
static apr_status_t impl_pollset_create(apr_pollset_t *pollset, apr_uint32_t size, apr_pool_t *p, apr_uint32_t flags) { apr_status_t rv = APR_SUCCESS; pollset->p = apr_palloc(p, sizeof(apr_pollset_private_t)); #if APR_HAS_THREADS if (flags & APR_POLLSET_THREADSAFE && ((rv = apr_thread_mutex_create(&pollset->p->ring_lock, APR_THREAD_MUTEX_DEFAULT, p)) != APR_SUCCESS)) { pollset->p = NULL; return rv; } #else if (flags & APR_POLLSET_THREADSAFE) { pollset->p = NULL; return APR_ENOTIMPL; } #endif pollset->p->waiting = 0; pollset->p->port_set = apr_palloc(p, size * sizeof(port_event_t)); pollset->p->port_fd = port_create(); if (pollset->p->port_fd < 0) { pollset->p = NULL; return apr_get_netos_error(); } { int flags; if ((flags = fcntl(pollset->p->port_fd, F_GETFD)) == -1) return errno; flags |= FD_CLOEXEC; if (fcntl(pollset->p->port_fd, F_SETFD, flags) == -1) return errno; } pollset->p->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t)); APR_RING_INIT(&pollset->p->query_ring, pfd_elem_t, link); APR_RING_INIT(&pollset->p->add_ring, pfd_elem_t, link); APR_RING_INIT(&pollset->p->free_ring, pfd_elem_t, link); APR_RING_INIT(&pollset->p->dead_ring, pfd_elem_t, link); return rv; }
static apr_status_t impl_pollset_add(apr_pollset_t *pollset, const apr_pollfd_t *descriptor) { struct epoll_event ev = {0}; int ret = -1; pfd_elem_t *elem = NULL; apr_status_t rv = APR_SUCCESS; ev.events = get_epoll_event(descriptor->reqevents); if (pollset->flags & APR_POLLSET_NOCOPY) { ev.data.ptr = (void *)descriptor; } else { pollset_lock_rings(); if (!APR_RING_EMPTY(&(pollset->p->free_ring), pfd_elem_t, link)) { elem = APR_RING_FIRST(&(pollset->p->free_ring)); APR_RING_REMOVE(elem, link); } else { elem = (pfd_elem_t *) apr_palloc(pollset->pool, sizeof(pfd_elem_t)); APR_RING_ELEM_INIT(elem, link); } elem->pfd = *descriptor; ev.data.ptr = elem; } if (descriptor->desc_type == APR_POLL_SOCKET) { ret = epoll_ctl(pollset->p->epoll_fd, EPOLL_CTL_ADD, descriptor->desc.s->socketdes, &ev); } else { ret = epoll_ctl(pollset->p->epoll_fd, EPOLL_CTL_ADD, descriptor->desc.f->filedes, &ev); } if (0 != ret) { rv = apr_get_netos_error(); } if (!(pollset->flags & APR_POLLSET_NOCOPY)) { if (rv != APR_SUCCESS) { APR_RING_INSERT_TAIL(&(pollset->p->free_ring), elem, pfd_elem_t, link); } else { APR_RING_INSERT_TAIL(&(pollset->p->query_ring), elem, pfd_elem_t, link); } pollset_unlock_rings(); } return rv; }
static apr_status_t impl_pollset_poll(apr_pollset_t *pollset, apr_interval_time_t timeout, apr_int32_t *num, const apr_pollfd_t **descriptors) { int ret; apr_status_t rv = APR_SUCCESS; if (timeout > 0) { timeout /= 1000; } #ifdef WIN32 ret = WSAPoll(pollset->p->pollset, pollset->nelts, (int)timeout); #else ret = poll(pollset->p->pollset, pollset->nelts, timeout); #endif (*num) = ret; if (ret < 0) { return apr_get_netos_error(); } else if (ret == 0) { return APR_TIMEUP; } else { apr_uint32_t i, j; for (i = 0, j = 0; i < pollset->nelts; i++) { if (pollset->p->pollset[i].revents != 0) { /* Check if the polled descriptor is our * wakeup pipe. In that case do not put it result set. */ if ((pollset->flags & APR_POLLSET_WAKEABLE) && pollset->p->query_set[i].desc_type == APR_POLL_FILE && pollset->p->query_set[i].desc.f == pollset->wakeup_pipe[0]) { apr_poll_drain_wakeup_pipe(pollset->wakeup_pipe); rv = APR_EINTR; } else { pollset->p->result_set[j] = pollset->p->query_set[i]; pollset->p->result_set[j].rtnevents = get_revent(pollset->p->pollset[i].revents); j++; } } } if (((*num) = j) > 0) rv = APR_SUCCESS; } if (descriptors && (*num)) *descriptors = pollset->p->result_set; return rv; }
static apr_status_t get_remote_addr(apr_socket_t *sock) { sock->remote_addr->salen = sizeof(sock->remote_addr->sa); if (getpeername(sock->socketdes, (struct sockaddr *)&sock->remote_addr->sa, &sock->remote_addr->salen) < 0) { return apr_get_netos_error(); } else { sock->remote_addr_unknown = 0; /* XXX assumes sin_port and sin6_port at same offset */ sock->remote_addr->port = ntohs(sock->remote_addr->sa.sin.sin_port); return APR_SUCCESS; } }
void lt_server_logger_print_socket( int priority, const char * aprcall, const char * format, ... ) { va_list ap; char error[1025]; if( priority > _logger_priority ) return; va_start( ap, format ); vprintf( format, ap ); va_end( ap ); apr_strerror( apr_get_netos_error(), error, 1024 ); printf( "APR SOCKET ERROR while calling %s: (%li) %s\n", aprcall, (long)apr_get_os_error(), error ); fflush( stdout ); }
apr_status_t apr_socket_atmark(apr_socket_t *sock, int *atmark) { #ifndef BEOS_R5 int oobmark; if (ioctl(sock->socketdes, SIOCATMARK, (void*) &oobmark) < 0) return apr_get_netos_error(); *atmark = (oobmark != 0); return APR_SUCCESS; #else /* BEOS_R5 */ return APR_ENOTIMPL; #endif }
static apr_status_t impl_pollcb_poll(apr_pollcb_t *pollcb, apr_interval_time_t timeout, apr_pollcb_cb_t func, void *baton) { int ret; apr_status_t rv = APR_SUCCESS; apr_uint32_t i; #ifdef WIN32 /* WSAPoll() requires at least one socket. */ if (pollcb->nelts == 0) { if (timeout > 0) { apr_sleep(timeout); return APR_TIMEUP; } return APR_SUCCESS; } if (timeout > 0) { timeout /= 1000; } ret = WSAPoll(pollcb->pollset.ps, pollcb->nelts, (int)timeout); #else if (timeout > 0) { timeout /= 1000; } ret = poll(pollcb->pollset.ps, pollcb->nelts, timeout); #endif if (ret < 0) { return apr_get_netos_error(); } else if (ret == 0) { return APR_TIMEUP; } else { for (i = 0; i < pollcb->nelts; i++) { if (pollcb->pollset.ps[i].revents != 0) { apr_pollfd_t *pollfd = pollcb->copyset[i]; pollfd->rtnevents = get_revent(pollcb->pollset.ps[i].revents); rv = func(baton, pollfd); if (rv) { return rv; } } } } return rv; }
static apr_status_t impl_pollcb_poll(apr_pollcb_t *pollcb, apr_interval_time_t timeout, apr_pollcb_cb_t func, void *baton) { int ret; apr_status_t rv = APR_SUCCESS; apr_uint32_t i; if (timeout > 0) { timeout /= 1000; } #ifdef WIN32 ret = WSAPoll(pollcb->pollset.ps, pollcb->nelts, (int)timeout); #else ret = poll(pollcb->pollset.ps, pollcb->nelts, timeout); #endif if (ret < 0) { return apr_get_netos_error(); } else if (ret == 0) { return APR_TIMEUP; } else { for (i = 0; i < pollcb->nelts; i++) { if (pollcb->pollset.ps[i].revents != 0) { apr_pollfd_t *pollfd = pollcb->copyset[i]; if ((pollcb->flags & APR_POLLSET_WAKEABLE) && pollfd->desc_type == APR_POLL_FILE && pollfd->desc.f == pollcb->wakeup_pipe[0]) { apr_poll_drain_wakeup_pipe(pollcb->wakeup_pipe); return APR_EINTR; } pollfd->rtnevents = get_revent(pollcb->pollset.ps[i].revents); rv = func(baton, pollfd); if (rv) { return rv; } } } } return rv; }
static apr_status_t impl_pollcb_create(apr_pollcb_t *pollcb, apr_uint32_t size, apr_pool_t *p, apr_uint32_t flags) { int fd; #ifdef HAVE_EPOLL_CREATE1 fd = epoll_create1(EPOLL_CLOEXEC); #else fd = epoll_create(size); #endif if (fd < 0) { return apr_get_netos_error(); } #ifndef HAVE_EPOLL_CREATE1 { int fd_flags; apr_status_t rv; if ((fd_flags = fcntl(fd, F_GETFD)) == -1) { rv = errno; close(fd); pollcb->fd = -1; return rv; } fd_flags |= FD_CLOEXEC; if (fcntl(fd, F_SETFD, fd_flags) == -1) { rv = errno; close(fd); pollcb->fd = -1; return rv; } } #endif pollcb->fd = fd; pollcb->pollset.epoll = apr_palloc(p, size * sizeof(struct epoll_event)); apr_pool_cleanup_register(p, pollcb, cb_cleanup, apr_pool_cleanup_null); return APR_SUCCESS; }
APR_DECLARE(apr_status_t) apr_socket_sendto(apr_socket_t *sock, apr_sockaddr_t *where, apr_int32_t flags, const char *buf, apr_size_t *len) { apr_ssize_t rv; rv = sendto(sock->socketdes, buf, (int)*len, flags, (const struct sockaddr*)&where->sa, where->salen); if (rv == SOCKET_ERROR) { *len = 0; return apr_get_netos_error(); } *len = rv; return APR_SUCCESS; }
static apr_status_t socket_cleanup(void *sock) { apr_socket_t *thesocket = sock; if (thesocket->socketdes != INVALID_SOCKET) { if (closesocket(thesocket->socketdes) == SOCKET_ERROR) { return apr_get_netos_error(); } thesocket->socketdes = INVALID_SOCKET; } #if APR_HAS_SENDFILE if (thesocket->overlapped) { CloseHandle(thesocket->overlapped->hEvent); thesocket->overlapped = NULL; } #endif return APR_SUCCESS; }
static apr_status_t impl_pollcb_poll(apr_pollcb_t *pollcb, apr_interval_time_t timeout, apr_pollcb_cb_t func, void *baton) { int ret, i; struct timespec tv, *tvptr; apr_status_t rv = APR_SUCCESS; if (timeout < 0) { tvptr = NULL; } else { tv.tv_sec = (long) apr_time_sec(timeout); tv.tv_nsec = (long) apr_time_usec(timeout) * 1000; tvptr = &tv; } ret = kevent(pollcb->fd, NULL, 0, pollcb->pollset.ke, 2 * pollcb->nalloc, tvptr); if (ret < 0) { rv = apr_get_netos_error(); } else if (ret == 0) { rv = APR_TIMEUP; } else { for (i = 0; i < ret; i++) { apr_pollfd_t *pollfd = (apr_pollfd_t *)(pollcb->pollset.ke[i].udata); pollfd->rtnevents = get_kqueue_revent(pollcb->pollset.ke[i].filter, pollcb->pollset.ke[i].flags); rv = func(baton, pollfd); if (rv) { return rv; } } } return rv; }
apr_status_t apr_socket_atmark(apr_socket_t *sock, int *atmark) { /* In 1.0 we rely on compile failure to assure all platforms grabbed * the correct header file support for SIOCATMARK, but we don't want * to fail the build of 0.9. Keep things good for the released branch. */ #ifdef SIOCATMARK int oobmark; if (ioctl(sock->socketdes, SIOCATMARK, (void*) &oobmark) < 0) return apr_get_netos_error(); *atmark = (oobmark != 0); return APR_SUCCESS; #else return APR_ENOTIMPL; #endif }
static apr_status_t impl_pollcb_add(apr_pollcb_t *pollcb, apr_pollfd_t *descriptor) { int ret, fd; if (descriptor->desc_type == APR_POLL_SOCKET) { fd = descriptor->desc.s->socketdes; } else { fd = descriptor->desc.f->filedes; } ret = port_associate(pollcb->fd, PORT_SOURCE_FD, fd, get_event(descriptor->reqevents), descriptor); if (ret == -1) { return apr_get_netos_error(); } return APR_SUCCESS; }
APR_DECLARE(apr_status_t) apr_getnameinfo(char **hostname, apr_sockaddr_t *sockaddr, apr_int32_t flags) { #if defined(HAVE_GETNAMEINFO) int rc; #if defined(NI_MAXHOST) char tmphostname[NI_MAXHOST]; #else char tmphostname[256]; #endif /* don't know if it is portable for getnameinfo() to set h_errno; * clear it then see if it was set */ SET_H_ERRNO(0); /* default flags are NI_NAMREQD; otherwise, getnameinfo() will return * a numeric address string if it fails to resolve the host name; * that is *not* what we want here * * For IPv4-mapped IPv6 addresses, drop down to IPv4 before calling * getnameinfo() to avoid getnameinfo bugs (MacOS X, glibc). */ #if APR_HAVE_IPV6 if (sockaddr->family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sockaddr->sa.sin6.sin6_addr)) { struct sockaddr_in tmpsa; tmpsa.sin_family = AF_INET; tmpsa.sin_port = 0; tmpsa.sin_addr.s_addr = ((apr_uint32_t *)sockaddr->ipaddr_ptr)[3]; #ifdef SIN6_LEN tmpsa.sin_len = sizeof(tmpsa); #endif rc = getnameinfo((const struct sockaddr *)&tmpsa, sizeof(tmpsa), tmphostname, sizeof(tmphostname), NULL, 0, flags != 0 ? flags : NI_NAMEREQD); } else #endif rc = getnameinfo((const struct sockaddr *)&sockaddr->sa, sockaddr->salen, tmphostname, sizeof(tmphostname), NULL, 0, flags != 0 ? flags : NI_NAMEREQD); if (rc != 0) { *hostname = NULL; #ifndef WIN32 /* something went wrong. Look at the EAI_ error code */ if (rc == EAI_SYSTEM) { /* EAI_SYSTEM System error returned in errno. */ /* IMHO, Implementations that set h_errno a simply broken. */ if (h_errno) { /* for broken implementations which set h_errno */ return h_errno + APR_OS_START_SYSERR; } else { /* "normal" case */ return errno + APR_OS_START_SYSERR; } } else #endif { #if defined(NEGATIVE_EAI) if (rc < 0) rc = -rc; #endif return rc + APR_OS_START_EAIERR; /* return the EAI_ error */ } } *hostname = sockaddr->hostname = apr_pstrdup(sockaddr->pool, tmphostname); return APR_SUCCESS; #else #if APR_HAS_THREADS && !defined(GETHOSTBYADDR_IS_THREAD_SAFE) && \ defined(HAVE_GETHOSTBYADDR_R) && !defined(BEOS) #ifdef GETHOSTBYNAME_R_HOSTENT_DATA struct hostent_data hd; #else char tmp[GETHOSTBYNAME_BUFLEN]; #endif int hosterror; struct hostent hs, *hptr; #if defined(GETHOSTBYNAME_R_HOSTENT_DATA) /* AIX, HP/UX, D/UX et alia */ gethostbyaddr_r((char *)&sockaddr->sa.sin.sin_addr, sizeof(struct in_addr), AF_INET, &hs, &hd); hptr = &hs; #else #if defined(GETHOSTBYNAME_R_GLIBC2) /* Linux glibc2+ */ gethostbyaddr_r((char *)&sockaddr->sa.sin.sin_addr, sizeof(struct in_addr), AF_INET, &hs, tmp, GETHOSTBYNAME_BUFLEN - 1, &hptr, &hosterror); #else /* Solaris, Irix et alia */ hptr = gethostbyaddr_r((char *)&sockaddr->sa.sin.sin_addr, sizeof(struct in_addr), AF_INET, &hs, tmp, GETHOSTBYNAME_BUFLEN, &hosterror); #endif /* !defined(GETHOSTBYNAME_R_GLIBC2) */ if (!hptr) { *hostname = NULL; return hosterror + APR_OS_START_SYSERR; } #endif /* !defined(GETHOSTBYNAME_R_HOSTENT_DATA) */ #else struct hostent *hptr; hptr = gethostbyaddr((char *)&sockaddr->sa.sin.sin_addr, sizeof(struct in_addr), AF_INET); #endif if (hptr) { *hostname = sockaddr->hostname = apr_pstrdup(sockaddr->pool, hptr->h_name); return APR_SUCCESS; } *hostname = NULL; #if defined(WIN32) return apr_get_netos_error(); #elif defined(OS2) return h_errno; #else return h_errno + APR_OS_START_SYSERR; #endif #endif }
static apr_status_t find_addresses(apr_sockaddr_t **sa, const char *hostname, apr_int32_t family, apr_port_t port, apr_int32_t flags, apr_pool_t *p) { struct hostent *hp; apr_sockaddr_t *prev_sa; int curaddr; #if APR_HAS_THREADS && !defined(GETHOSTBYNAME_IS_THREAD_SAFE) && \ defined(HAVE_GETHOSTBYNAME_R) && !defined(BEOS) #ifdef GETHOSTBYNAME_R_HOSTENT_DATA struct hostent_data hd; #else /* If you see ERANGE, that means GETHOSBYNAME_BUFLEN needs to be * bumped. */ char tmp[GETHOSTBYNAME_BUFLEN]; #endif int hosterror; #endif struct hostent hs; struct in_addr ipaddr; char *addr_list[2]; const char *orig_hostname = hostname; if (hostname == NULL) { /* if we are given a NULL hostname, assume '0.0.0.0' */ hostname = "0.0.0.0"; } if (*hostname >= '0' && *hostname <= '9' && strspn(hostname, "0123456789.") == strlen(hostname)) { ipaddr.s_addr = inet_addr(hostname); addr_list[0] = (char *)&ipaddr; addr_list[1] = NULL; /* just one IP in list */ hs.h_addr_list = (char **)addr_list; hp = &hs; } else { #if APR_HAS_THREADS && !defined(GETHOSTBYNAME_IS_THREAD_SAFE) && \ defined(HAVE_GETHOSTBYNAME_R) && !defined(BEOS) #if defined(GETHOSTBYNAME_R_HOSTENT_DATA) /* AIX, HP/UX, D/UX et alia */ gethostbyname_r(hostname, &hs, &hd); hp = &hs; #else #if defined(GETHOSTBYNAME_R_GLIBC2) /* Linux glibc2+ */ gethostbyname_r(hostname, &hs, tmp, GETHOSTBYNAME_BUFLEN - 1, &hp, &hosterror); #else /* Solaris, Irix et alia */ hp = gethostbyname_r(hostname, &hs, tmp, GETHOSTBYNAME_BUFLEN - 1, &hosterror); #endif /* !defined(GETHOSTBYNAME_R_GLIBC2) */ if (!hp) { return (hosterror + APR_OS_START_SYSERR); } #endif /* !defined(GETHOSTBYNAME_R_HOSTENT_DATA) */ #else hp = gethostbyname(hostname); #endif if (!hp) { #ifdef WIN32 return apr_get_netos_error(); #else return (h_errno + APR_OS_START_SYSERR); #endif } } prev_sa = NULL; curaddr = 0; while (hp->h_addr_list[curaddr]) { apr_sockaddr_t *new_sa = apr_pcalloc(p, sizeof(apr_sockaddr_t)); new_sa->pool = p; new_sa->sa.sin.sin_addr = *(struct in_addr *)hp->h_addr_list[curaddr]; apr_sockaddr_vars_set(new_sa, AF_INET, port); if (!prev_sa) { /* first element in new list */ if (orig_hostname) { new_sa->hostname = apr_pstrdup(p, orig_hostname); } *sa = new_sa; } else { new_sa->hostname = prev_sa->hostname; prev_sa->next = new_sa; } prev_sa = new_sa; ++curaddr; } return APR_SUCCESS; }