diff options
author | Andrew Bartlett <abartlet@samba.org> | 2009-03-11 07:58:42 +1100 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2009-03-11 07:58:42 +1100 |
commit | 3d0a727f575942b767e396b694f6529259528a17 (patch) | |
tree | 8ea6acdfe1b043abe06a0f3d78dcbc1b55d6f146 /lib | |
parent | c218d3e1173355acf025471a10b4b6425b9c086b (diff) | |
parent | 3d280639c4652d6cd35577e333bcd46c2517754c (diff) | |
download | samba-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.c | 132 | ||||
-rw-r--r-- | lib/socket_wrapper/socket_wrapper.h | 12 | ||||
-rw-r--r-- | lib/tevent/tevent.h | 10 | ||||
-rw-r--r-- | lib/tevent/tevent_internal.h | 2 | ||||
-rw-r--r-- | lib/tevent/tevent_req.c | 21 |
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) { |