summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordreid <dreid@13f79535-47bb-0310-9956-ffa450edef68>2001-03-08 19:58:39 +0000
committerdreid <dreid@13f79535-47bb-0310-9956-ffa450edef68>2001-03-08 19:58:39 +0000
commit8347023dfd17c66eb82a115a2ba8d24b6db235b4 (patch)
tree83b9cf126afbaa2fc470b64f7d7421da653df5e6
parent910dc50cceb7f4981cf5331696b926072c916903 (diff)
downloadlibapr-8347023dfd17c66eb82a115a2ba8d24b6db235b4.tar.gz
OK, so this commit adds basic UDP support for Unix. I've had this on
my To Do list for a while now and I've been feeling guilty which is why I'm only posting the Unix code. I'm pretty sure the code is general enough that the other platforms will have no problem in using it, but I can't test on those platforms. I'll do BeOS when I get a spare 5 minutes. The network code could probably do with a review for common code anyways. Tested and working with both IPv4 and IPv6 on FreeBSD. git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@61352 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--include/apr_network_io.h21
-rw-r--r--network_io/unix/sendrecv.c76
2 files changed, 97 insertions, 0 deletions
diff --git a/include/apr_network_io.h b/include/apr_network_io.h
index c641458f5..585d64245 100644
--- a/include/apr_network_io.h
+++ b/include/apr_network_io.h
@@ -436,6 +436,27 @@ APR_DECLARE(apr_status_t) apr_sendv(apr_socket_t *sock,
const struct iovec *vec,
apr_int32_t nvec, apr_size_t *len);
+/**
+ * @param sock The socket to send from
+ * @param where The apr_sockaddr_t describing where to send the data
+ * @param data The data to send
+ * @param len The length of the data to send
+ */
+APR_DECLARE(apr_status_t) apr_sendto(apr_socket_t *sock, apr_sockaddr_t *where,
+ apr_int32_t flags, const char *buf,
+ apr_size_t *len);
+
+/**
+ * @param from The apr_sockaddr_t to fill in the recipient info
+ * @param sock The socket to use
+ * @param buf The buffer to use
+ * @param len The length of the available buffer
+ */
+
+APR_DECLARE(apr_status_t) apr_recvfrom(apr_sockaddr_t *from, apr_socket_t *sock,
+ apr_int32_t flags, char *buf,
+ apr_size_t *len);
+
#if APR_HAS_SENDFILE
/**
diff --git a/network_io/unix/sendrecv.c b/network_io/unix/sendrecv.c
index 25d292b59..f452e4747 100644
--- a/network_io/unix/sendrecv.c
+++ b/network_io/unix/sendrecv.c
@@ -162,6 +162,82 @@ apr_status_t apr_recv(apr_socket_t *sock, char *buf, apr_size_t *len)
return APR_SUCCESS;
}
+apr_status_t apr_sendto(apr_socket_t *sock, apr_sockaddr_t *where,
+ apr_int32_t flags, const char *buf, apr_size_t *len)
+{
+ ssize_t rv;
+
+ do {
+ rv = sendto(sock->socketdes, buf, (*len), flags,
+ (const struct sockaddr*)&where->sa,
+ where->salen);
+ } while (rv == -1 && errno == EINTR);
+
+ if (rv == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)
+ && sock->timeout != 0) {
+ apr_status_t arv = wait_for_io_or_timeout(sock, 0);
+ if (arv != APR_SUCCESS) {
+ *len = 0;
+ return arv;
+ } else {
+ do {
+ rv = sendto(sock->socketdes, buf, (*len), flags,
+ (const struct sockaddr*)&where->sa,
+ where->salen);
+ } while (rv == -1 && errno == EINTR);
+ }
+ }
+ if (rv == -1) {
+ *len = 0;
+ return errno;
+ }
+ *len = rv;
+ return APR_SUCCESS;
+}
+
+apr_status_t apr_recvfrom(apr_sockaddr_t *from, apr_socket_t *sock,
+ apr_int32_t flags, char *buf,
+ apr_size_t *len)
+{
+ ssize_t rv;
+
+ if (from == NULL){
+ return APR_ENOMEM;
+ /* Not sure if this is correct. Maybe we should just allocate
+ the memory??
+ */
+ }
+
+ do {
+ rv = recvfrom(sock->socketdes, buf, (*len), flags,
+ (struct sockaddr*)&from->sa, &from->salen);
+ } while (rv == -1 && errno == EINTR);
+
+ if (rv == -1 && (errno == EAGAIN || errno == EWOULDBLOCK) &&
+ sock->timeout != 0) {
+ apr_status_t arv = wait_for_io_or_timeout(sock, 1);
+ if (arv != APR_SUCCESS) {
+ *len = 0;
+ return arv;
+ } else {
+ do {
+ rv = recvfrom(sock->socketdes, buf, (*len), flags,
+ (struct sockaddr*)&from->sa, &from->salen);
+ } while (rv == -1 && errno == EINTR);
+ }
+ }
+ if (rv == -1) {
+ (*len) = 0;
+ return errno;
+ }
+
+ (*len) = rv;
+ if (rv == 0)
+ return APR_EOF;
+
+ return APR_SUCCESS;
+}
+
#ifdef HAVE_WRITEV
apr_status_t apr_sendv(apr_socket_t * sock, const struct iovec *vec,
apr_int32_t nvec, apr_size_t *len)