summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2009-03-11 07:58:42 +1100
committerAndrew Bartlett <abartlet@samba.org>2009-03-11 07:58:42 +1100
commit3d0a727f575942b767e396b694f6529259528a17 (patch)
tree8ea6acdfe1b043abe06a0f3d78dcbc1b55d6f146 /lib
parentc218d3e1173355acf025471a10b4b6425b9c086b (diff)
parent3d280639c4652d6cd35577e333bcd46c2517754c (diff)
downloadsamba-3d0a727f575942b767e396b694f6529259528a17.tar.gz
samba-3d0a727f575942b767e396b694f6529259528a17.tar.bz2
samba-3d0a727f575942b767e396b694f6529259528a17.zip
Merge branch 'master' of ssh://git.samba.org/data/git/samba into wspp-schema
Diffstat (limited to 'lib')
-rw-r--r--lib/socket_wrapper/socket_wrapper.c132
-rw-r--r--lib/socket_wrapper/socket_wrapper.h12
-rw-r--r--lib/tevent/tevent.h10
-rw-r--r--lib/tevent/tevent_internal.h2
-rw-r--r--lib/tevent/tevent_req.c21
5 files changed, 168 insertions, 9 deletions
diff --git a/lib/socket_wrapper/socket_wrapper.c b/lib/socket_wrapper/socket_wrapper.c
index 97e60468c4..44082e78a1 100644
--- a/lib/socket_wrapper/socket_wrapper.c
+++ b/lib/socket_wrapper/socket_wrapper.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) Jelmer Vernooij 2005,2008 <jelmer@samba.org>
- * Copyright (C) Stefan Metzmacher 2006 <metze@samba.org>
+ * Copyright (C) Stefan Metzmacher 2006-2009 <metze@samba.org>
*
* All rights reserved.
*
@@ -121,6 +121,8 @@
#define real_ioctl ioctl
#define real_recv recv
#define real_send send
+#define real_readv readv
+#define real_writev writev
#define real_socket socket
#define real_close close
#endif
@@ -1698,13 +1700,7 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t ad
si->peername_len = addrlen;
si->peername = sockaddr_dup(serv_addr, addrlen);
si->connected = 1;
- }
-
- if (si->type != SOCK_STREAM) {
- return ret;
- }
- if (ret == 0) {
swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0);
swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0);
} else {
@@ -2018,6 +2014,128 @@ _PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
return ret;
}
+int swrap_readv(int s, const struct iovec *vector, size_t count)
+{
+ int ret;
+ struct socket_info *si = find_socket_info(s);
+ struct iovec v;
+
+ if (!si) {
+ return real_readv(s, vector, count);
+ }
+
+ /* we read 1500 bytes as maximum */
+ if (count > 0) {
+ size_t i, len = 0;
+
+ for (i=0; i < count; i++) {
+ size_t nlen;
+ nlen = len + vector[i].iov_len;
+ if (nlen > 1500) {
+ break;
+ }
+ }
+ count = i;
+ if (count == 0) {
+ v = vector[0];
+ v.iov_len = MIN(v.iov_len, 1500);
+ vector = &v;
+ count = 1;
+ }
+ }
+
+ ret = real_readv(s, vector, count);
+ if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
+ swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
+ } else if (ret == 0) { /* END OF FILE */
+ swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0);
+ } else if (ret > 0) {
+ uint8_t *buf;
+ off_t ofs = 0;
+ size_t i;
+
+ /* we capture it as one single packet */
+ buf = (uint8_t *)malloc(ret);
+ if (!buf) {
+ /* we just not capture the packet */
+ errno = 0;
+ return ret;
+ }
+
+ for (i=0; i < count; i++) {
+ memcpy(buf + ofs,
+ vector[i].iov_base,
+ vector[i].iov_len);
+ ofs += vector[i].iov_len;
+ }
+
+ swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret);
+ free(buf);
+ }
+
+ return ret;
+}
+
+int swrap_writev(int s, const struct iovec *vector, size_t count)
+{
+ int ret;
+ struct socket_info *si = find_socket_info(s);
+ struct iovec v;
+
+ if (!si) {
+ return real_writev(s, vector, count);
+ }
+
+ /* we write 1500 bytes as maximum */
+ if (count > 0) {
+ size_t i, len = 0;
+
+ for (i=0; i < count; i++) {
+ size_t nlen;
+ nlen = len + vector[i].iov_len;
+ if (nlen > 1500) {
+ break;
+ }
+ }
+ count = i;
+ if (count == 0) {
+ v = vector[0];
+ v.iov_len = MIN(v.iov_len, 1500);
+ vector = &v;
+ count = 1;
+ }
+ }
+
+ ret = real_writev(s, vector, count);
+ if (ret == -1) {
+ swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
+ } else {
+ uint8_t *buf;
+ off_t ofs = 0;
+ size_t i;
+
+ /* we capture it as one single packet */
+ buf = (uint8_t *)malloc(ret);
+ if (!buf) {
+ /* we just not capture the packet */
+ errno = 0;
+ return ret;
+ }
+
+ for (i=0; i < count; i++) {
+ memcpy(buf + ofs,
+ vector[i].iov_base,
+ vector[i].iov_len);
+ ofs += vector[i].iov_len;
+ }
+
+ swrap_dump_packet(si, NULL, SWRAP_SEND, buf, ret);
+ free(buf);
+ }
+
+ return ret;
+}
+
_PUBLIC_ int swrap_close(int fd)
{
struct socket_info *si = find_socket_info(fd);
diff --git a/lib/socket_wrapper/socket_wrapper.h b/lib/socket_wrapper/socket_wrapper.h
index cc8b937608..b2d44769ff 100644
--- a/lib/socket_wrapper/socket_wrapper.h
+++ b/lib/socket_wrapper/socket_wrapper.h
@@ -52,6 +52,8 @@ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct
int swrap_ioctl(int s, int req, void *ptr);
ssize_t swrap_recv(int s, void *buf, size_t len, int flags);
ssize_t swrap_send(int s, const void *buf, size_t len, int flags);
+int swrap_readv(int s, const struct iovec *vector, size_t count);
+int swrap_writev(int s, const struct iovec *vector, size_t count);
int swrap_close(int);
#ifdef SOCKET_WRAPPER_REPLACE
@@ -121,6 +123,16 @@ int swrap_close(int);
#endif
#define send(s,buf,len,flags) swrap_send(s,buf,len,flags)
+#ifdef readv
+#undef readv
+#endif
+#define readv(s, vector, count) swrap_readv(s,vector, count)
+
+#ifdef writev
+#undef writev
+#endif
+#define writev(s, vector, count) swrap_writev(s,vector, count)
+
#ifdef socket
#undef socket
#endif
diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h
index 5089d18ec2..2dadfc1abe 100644
--- a/lib/tevent/tevent.h
+++ b/lib/tevent/tevent.h
@@ -165,7 +165,11 @@ enum tevent_req_state {
/**
* No memory in between
*/
- TEVENT_REQ_NO_MEMORY
+ TEVENT_REQ_NO_MEMORY,
+ /**
+ * the request is already received by the caller
+ */
+ TEVENT_REQ_RECEIVED
};
/**
@@ -193,6 +197,8 @@ void *_tevent_req_data(struct tevent_req *req);
#define tevent_req_callback_data(_req, _type) \
talloc_get_type_abort(_tevent_req_callback_data(_req), _type)
+#define tevent_req_callback_data_void(_req) \
+ _tevent_req_callback_data(_req)
#define tevent_req_data(_req, _type) \
talloc_get_type_abort(_tevent_req_data(_req), _type)
@@ -238,6 +244,8 @@ bool tevent_req_is_error(struct tevent_req *req,
enum tevent_req_state *state,
uint64_t *error);
+void tevent_req_received(struct tevent_req *req);
+
struct tevent_req *tevent_wakeup_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct timeval wakeup_time);
diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h
index fa73b22a48..5a645ecb60 100644
--- a/lib/tevent/tevent_internal.h
+++ b/lib/tevent/tevent_internal.h
@@ -56,7 +56,7 @@ struct tevent_req {
/**
* @brief A function to overwrite the default print function
*
- * The implementation doing the work may want to imeplement a
+ * The implementation doing the work may want to implement a
* custom function to print the text representation of the async
* request.
*/
diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c
index 9b3e00ec8f..3832088b34 100644
--- a/lib/tevent/tevent_req.c
+++ b/lib/tevent/tevent_req.c
@@ -256,6 +256,27 @@ bool tevent_req_is_in_progress(struct tevent_req *req)
return false;
}
+/**
+ * @brief This function destroys the attached private data
+ * @param[in] req The finished request
+ *
+ * This function can be called as last action of a _recv()
+ * function, it destroys the data attached to the tevent_req.
+ */
+void tevent_req_received(struct tevent_req *req)
+{
+ talloc_free(req->data);
+ req->data = NULL;
+ req->private_print = NULL;
+
+ talloc_free(req->internal.trigger);
+ req->internal.trigger = NULL;
+ talloc_free(req->internal.timer);
+ req->internal.timer = NULL;
+
+ req->internal.state = TEVENT_REQ_RECEIVED;
+}
+
bool tevent_req_poll(struct tevent_req *req,
struct tevent_context *ev)
{