APR_DECLARE(apr_status_t) apr_socket_atreadeof(apr_socket_t *sock, int *atreadeof) { apr_pollfd_t pfds[1]; apr_status_t rv; apr_int32_t nfds; /* The purpose here is to return APR_SUCCESS only in cases in * which it can be unambiguously determined whether or not the * socket will return EOF on next read. In case of an unexpected * error, return that. */ pfds[0].reqevents = APR_POLLIN; pfds[0].desc_type = APR_POLL_SOCKET; pfds[0].desc.s = sock; do { rv = apr_poll(&pfds[0], 1, &nfds, 0); } while (APR_STATUS_IS_EINTR(rv)); if (APR_STATUS_IS_TIMEUP(rv)) { /* Read buffer empty -> subsequent reads would block, so, * definitely not at EOF. */ *atreadeof = 0; return APR_SUCCESS; } else if (rv) { /* Some other error -> unexpected error. */ return rv; } else if (nfds == 1 && pfds[0].rtnevents == APR_POLLIN) { apr_sockaddr_t unused; apr_size_t len = 1; char buf; /* The socket is readable - peek to see whether it returns EOF * without consuming bytes from the socket buffer. */ rv = apr_socket_recvfrom(&unused, sock, MSG_PEEK, &buf, &len); if (rv == APR_EOF) { *atreadeof = 1; return APR_SUCCESS; } else if (rv) { /* Read error -> unexpected error. */ return rv; } else { *atreadeof = 0; return APR_SUCCESS; } } /* Should not fall through here. */ return APR_EGENERAL; }
static int socket_recvfrom(lua_State *L) { lua_apr_socket *object; apr_status_t status; apr_sockaddr_t address = { 0 }; apr_size_t buflen; apr_int32_t flags; char buffer[1024], ip_addr[APRMAXHOSTLEN]; char *bufptr; int i; /* Validate arguments. */ object = socket_check(L, 1, 1); buflen = luaL_optint(L, 2, sizeof buffer); /* Use dynamically allocated buffer only when necessary. */ bufptr = (buflen > sizeof buffer) ? lua_newuserdata(L, buflen) : &buffer[0]; flags = 0; status = apr_socket_recvfrom(&address, object->handle, flags, bufptr, &buflen); if (status != APR_SUCCESS) return push_error_status(L, status); /* Convert the socket address to a Lua table. */ lua_newtable(L); /* Get the IP address in numeric format. */ status = apr_sockaddr_ip_getbuf(ip_addr, sizeof ip_addr, &address); if (status == APR_SUCCESS) lua_pushstring(L, ip_addr), lua_setfield(L, -2, "address"); /* Get the port number. */ lua_pushnumber(L, address.port), lua_setfield(L, -2, "port"); /* Get the address family. */ for (i = 0; i < count(family_values); i++) if (family_values[i] == address.family) { lua_pushstring(L, family_options[i]); lua_setfield(L, -2, "family"); break; } /* Push the received data. */ lua_pushlstring(L, bufptr, buflen); /* Return address table and received data. */ return 2; }
SWITCH_DECLARE(switch_status_t) switch_socket_recvfrom(switch_sockaddr_t *from, switch_socket_t *sock, int32_t flags, char *buf, size_t *len) { apr_status_t r = SWITCH_STATUS_GENERR; if (from && sock && (r = apr_socket_recvfrom(from, sock, flags, buf, len)) == APR_SUCCESS) { from->port = ntohs(from->sa.sin.sin_port); /* from->ipaddr_ptr = &(from->sa.sin.sin_addr); * from->ipaddr_ptr = inet_ntoa(from->sa.sin.sin_addr); */ } if (r == 35) { r = SWITCH_STATUS_BREAK; } return r; }
static void recv_msg(apr_socket_t **sockarray, int which, apr_pool_t *p, abts_case *tc) { apr_size_t buflen = 5; char *buffer = apr_pcalloc(p, sizeof(char) * (buflen + 1)); apr_sockaddr_t *recsa; apr_status_t rv; ABTS_PTR_NOTNULL(tc, sockarray[which]); apr_sockaddr_info_get(&recsa, "127.0.0.1", APR_UNSPEC, 7770, 0, p); rv = apr_socket_recvfrom(recsa, sockarray[which], 0, buffer, &buflen); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); ABTS_SIZE_EQUAL(tc, strlen("hello"), buflen); ABTS_STR_EQUAL(tc, "hello", buffer); }
static void recv_msg(apr_socket_t **sockarray, int which, apr_pool_t *p, CuTest *tc) { apr_size_t buflen = 5; char *buffer = apr_pcalloc(p, sizeof(char) * (buflen + 1)); apr_sockaddr_t *recsa; apr_status_t rv; CuAssertPtrNotNull(tc, sockarray[which]); apr_sockaddr_info_get(&recsa, "127.0.0.1", APR_UNSPEC, 7770, 0, p); rv = apr_socket_recvfrom(recsa, sockarray[which], 0, buffer, &buflen); CuAssertIntEquals(tc, APR_SUCCESS, rv); CuAssertIntEquals(tc, strlen("hello"), buflen); CuAssertStrEquals(tc, "hello", buffer); }
static void sendto_receivefrom_helper(abts_case *tc, const char *addr, int family) { apr_status_t rv; apr_socket_t *sock = NULL; apr_socket_t *sock2 = NULL; char sendbuf[STRLEN] = "APR_INET, SOCK_DGRAM"; char recvbuf[80]; char *ip_addr; apr_port_t fromport; apr_sockaddr_t *from; apr_sockaddr_t *to; apr_size_t len = 30; rv = apr_socket_create(&sock, family, SOCK_DGRAM, 0, p); #if APR_HAVE_IPV6 if ((family == APR_INET6) && APR_STATUS_IS_EAFNOSUPPORT(rv)) { ABTS_NOT_IMPL(tc, "IPv6 not enabled"); return; } #endif ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); if (rv != APR_SUCCESS) return; rv = apr_socket_create(&sock2, family, SOCK_DGRAM, 0, p); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); if (rv != APR_SUCCESS) return; rv = apr_sockaddr_info_get(&to, addr, family, 7772, 0, p); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); rv = apr_sockaddr_info_get(&from, addr, family, 7771, 0, p); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); rv = apr_socket_opt_set(sock, APR_SO_REUSEADDR, 1); APR_ASSERT_SUCCESS(tc, "Could not set REUSEADDR on socket", rv); rv = apr_socket_opt_set(sock2, APR_SO_REUSEADDR, 1); APR_ASSERT_SUCCESS(tc, "Could not set REUSEADDR on socket2", rv); rv = apr_socket_bind(sock, to); APR_ASSERT_SUCCESS(tc, "Could not bind socket", rv); if (rv != APR_SUCCESS) return; rv = apr_socket_bind(sock2, from); APR_ASSERT_SUCCESS(tc, "Could not bind second socket", rv); if (rv != APR_SUCCESS) return; len = STRLEN; rv = apr_socket_sendto(sock2, to, 0, sendbuf, &len); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); ABTS_SIZE_EQUAL(tc, STRLEN, len); /* fill the "from" sockaddr with a random address from another * family to ensure that recvfrom sets it up properly. */ #if APR_HAVE_IPV6 if (family == APR_INET) rv = apr_sockaddr_info_get(&from, "3ffE:816e:abcd:1234::1", APR_INET6, 4242, 0, p); else #endif rv = apr_sockaddr_info_get(&from, "127.1.2.3", APR_INET, 4242, 0, p); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); len = 80; rv = apr_socket_recvfrom(from, sock, 0, recvbuf, &len); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); ABTS_SIZE_EQUAL(tc, STRLEN, len); ABTS_STR_EQUAL(tc, "APR_INET, SOCK_DGRAM", recvbuf); apr_sockaddr_ip_get(&ip_addr, from); fromport = from->port; ABTS_STR_EQUAL(tc, addr, ip_addr); ABTS_INT_EQUAL(tc, 7771, fromport); apr_socket_close(sock); apr_socket_close(sock2); }
static void sendto_receivefrom(abts_case *tc, void *data) { apr_status_t rv; apr_socket_t *sock = NULL; apr_socket_t *sock2 = NULL; char sendbuf[STRLEN] = "APR_INET, SOCK_DGRAM"; char recvbuf[80]; char *ip_addr; apr_port_t fromport; apr_sockaddr_t *from; apr_sockaddr_t *to; apr_size_t len = 30; int family; const char *addr; #if APR_HAVE_IPV6 family = APR_INET6; addr = "::1"; rv = apr_socket_create(&sock, family, SOCK_DGRAM, 0, p); if (V6_NOT_ENABLED(rv)) { #endif family = APR_INET; addr = "127.0.0.1"; rv = apr_socket_create(&sock, family, SOCK_DGRAM, 0, p); #if APR_HAVE_IPV6 } #endif ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); rv = apr_socket_create(&sock2, family, SOCK_DGRAM, 0, p); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); rv = apr_sockaddr_info_get(&to, addr, APR_UNSPEC, 7772, 0, p); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); rv = apr_sockaddr_info_get(&from, addr, APR_UNSPEC, 7771, 0, p); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); rv = apr_socket_opt_set(sock, APR_SO_REUSEADDR, 1); APR_ASSERT_SUCCESS(tc, "Could not set REUSEADDR on socket", rv); rv = apr_socket_opt_set(sock2, APR_SO_REUSEADDR, 1); APR_ASSERT_SUCCESS(tc, "Could not set REUSEADDR on socket2", rv); rv = apr_socket_bind(sock, to); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); rv = apr_socket_bind(sock2, from); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); len = STRLEN; rv = apr_socket_sendto(sock2, to, 0, sendbuf, &len); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); ABTS_INT_EQUAL(tc, STRLEN, len); len = 80; rv = apr_socket_recvfrom(from, sock, 0, recvbuf, &len); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); ABTS_INT_EQUAL(tc, STRLEN, len); ABTS_STR_EQUAL(tc, "APR_INET, SOCK_DGRAM", recvbuf); apr_sockaddr_ip_get(&ip_addr, from); fromport = from->port; ABTS_STR_EQUAL(tc, addr, ip_addr); ABTS_INT_EQUAL(tc, 7771, fromport); apr_socket_close(sock); apr_socket_close(sock2); }
/* deprecated */ apr_status_t apr_recvfrom(apr_sockaddr_t *from, apr_socket_t *sock, apr_int32_t flags, char *buf, apr_size_t *len) { return apr_socket_recvfrom(from, sock, flags, buf, len); }