lib/tsocket: add a fast path to tsocket_writev_send/recv()
[ira/wip.git] / lib / tsocket / tsocket.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Copyright (C) Stefan Metzmacher 2009
5
6      ** NOTE! The following LGPL license applies to the tevent
7      ** library. This does NOT imply that all of Samba is released
8      ** under the LGPL
9
10    This library is free software; you can redistribute it and/or
11    modify it under the terms of the GNU Lesser General Public
12    License as published by the Free Software Foundation; either
13    version 3 of the License, or (at your option) any later version.
14
15    This library is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    Lesser General Public License for more details.
19
20    You should have received a copy of the GNU Lesser General Public
21    License along with this library; if not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "replace.h"
25 #include "system/network.h"
26 #include "tsocket.h"
27 #include "tsocket_internal.h"
28
29 static int tsocket_context_destructor(struct tsocket_context *sock)
30 {
31         tsocket_disconnect(sock);
32         return 0;
33 }
34
35 struct tsocket_context *_tsocket_context_create(TALLOC_CTX *mem_ctx,
36                                                 const struct tsocket_context_ops *ops,
37                                                 void *pstate,
38                                                 size_t psize,
39                                                 const char *type,
40                                                 const char *location)
41 {
42         void **ppstate = (void **)pstate;
43         struct tsocket_context *sock;
44
45         sock = talloc_zero(mem_ctx, struct tsocket_context);
46         if (!sock) {
47                 return NULL;
48         }
49         sock->ops = ops;
50         sock->location = location;
51         sock->private_data = talloc_size(sock, psize);
52         if (!sock->private_data) {
53                 talloc_free(sock);
54                 return NULL;
55         }
56         talloc_set_name_const(sock->private_data, type);
57
58         talloc_set_destructor(sock, tsocket_context_destructor);
59
60         *ppstate = sock->private_data;
61         return sock;
62 }
63
64 int tsocket_set_event_context(struct tsocket_context *sock,
65                               struct tevent_context *ev)
66 {
67         return sock->ops->set_event_context(sock, ev);
68 }
69
70 int tsocket_set_readable_handler(struct tsocket_context *sock,
71                                  tsocket_event_handler_t handler,
72                                  void *private_data)
73 {
74         return sock->ops->set_read_handler(sock, handler, private_data);
75 }
76
77 int tsocket_set_writeable_handler(struct tsocket_context *sock,
78                                   tsocket_event_handler_t handler,
79                                   void *private_data)
80 {
81         return sock->ops->set_write_handler(sock, handler, private_data);
82 }
83
84 int tsocket_connect(struct tsocket_context *sock,
85                     const struct tsocket_address *remote_addr)
86 {
87         return sock->ops->connect_to(sock, remote_addr);
88 }
89
90 int tsocket_listen(struct tsocket_context *sock,
91                    int queue_size)
92 {
93         return sock->ops->listen_on(sock, queue_size);
94 }
95
96 int _tsocket_accept(struct tsocket_context *sock,
97                     TALLOC_CTX *mem_ctx,
98                     struct tsocket_context **new_sock,
99                     const char *location)
100 {
101         return sock->ops->accept_new(sock, mem_ctx, new_sock, location);
102 }
103
104 ssize_t tsocket_pending(struct tsocket_context *sock)
105 {
106         return sock->ops->pending_data(sock);
107 }
108
109 int tsocket_readv(struct tsocket_context *sock,
110                   const struct iovec *vector, size_t count)
111 {
112         return sock->ops->readv_data(sock, vector, count);
113 }
114
115 int tsocket_writev(struct tsocket_context *sock,
116                    const struct iovec *vector, size_t count)
117 {
118         return sock->ops->writev_data(sock, vector, count);
119 }
120
121 ssize_t tsocket_recvfrom(struct tsocket_context *sock,
122                          uint8_t *data, size_t len,
123                          TALLOC_CTX *addr_ctx,
124                          struct tsocket_address **src_addr)
125 {
126         return sock->ops->recvfrom_data(sock, data, len, addr_ctx, src_addr);
127 }
128
129 ssize_t tsocket_sendto(struct tsocket_context *sock,
130                        const uint8_t *data, size_t len,
131                        const struct tsocket_address *dest_addr)
132 {
133         return sock->ops->sendto_data(sock, data, len, dest_addr);
134 }
135
136 int tsocket_get_status(const struct tsocket_context *sock)
137 {
138         return sock->ops->get_status(sock);
139 }
140
141 int _tsocket_get_local_address(const struct tsocket_context *sock,
142                                TALLOC_CTX *mem_ctx,
143                                struct tsocket_address **local_addr,
144                                const char *location)
145 {
146         return sock->ops->get_local_address(sock, mem_ctx,
147                                             local_addr, location);
148 }
149
150 int _tsocket_get_remote_address(const struct tsocket_context *sock,
151                                 TALLOC_CTX *mem_ctx,
152                                 struct tsocket_address **remote_addr,
153                                 const char *location)
154 {
155         return sock->ops->get_remote_address(sock, mem_ctx,
156                                              remote_addr, location);
157 }
158
159 int tsocket_get_option(const struct tsocket_context *sock,
160                        const char *option,
161                        TALLOC_CTX *mem_ctx,
162                        char **value)
163 {
164         return sock->ops->get_option(sock, option, mem_ctx, value);
165 }
166
167 int tsocket_set_option(const struct tsocket_context *sock,
168                        const char *option,
169                        bool force,
170                        const char *value)
171 {
172         return sock->ops->set_option(sock, option, force, value);
173 }
174
175 void tsocket_disconnect(struct tsocket_context *sock)
176 {
177         sock->ops->disconnect(sock);
178 }
179
180 struct tsocket_address *_tsocket_address_create(TALLOC_CTX *mem_ctx,
181                                                 const struct tsocket_address_ops *ops,
182                                                 void *pstate,
183                                                 size_t psize,
184                                                 const char *type,
185                                                 const char *location)
186 {
187         void **ppstate = (void **)pstate;
188         struct tsocket_address *addr;
189
190         addr = talloc_zero(mem_ctx, struct tsocket_address);
191         if (!addr) {
192                 return NULL;
193         }
194         addr->ops = ops;
195         addr->location = location;
196         addr->private_data = talloc_size(addr, psize);
197         if (!addr->private_data) {
198                 talloc_free(addr);
199                 return NULL;
200         }
201         talloc_set_name_const(addr->private_data, type);
202
203         *ppstate = addr->private_data;
204         return addr;
205 }
206
207 char *tsocket_address_string(const struct tsocket_address *addr,
208                              TALLOC_CTX *mem_ctx)
209 {
210         if (!addr) {
211                 return talloc_strdup(mem_ctx, "NULL");
212         }
213         return addr->ops->string(addr, mem_ctx);
214 }
215
216 struct tsocket_address *_tsocket_address_copy(const struct tsocket_address *addr,
217                                               TALLOC_CTX *mem_ctx,
218                                               const char *location)
219 {
220         return addr->ops->copy(addr, mem_ctx, location);
221 }
222
223 int _tsocket_address_create_socket(const struct tsocket_address *addr,
224                                    enum tsocket_type type,
225                                    TALLOC_CTX *mem_ctx,
226                                    struct tsocket_context **sock,
227                                    const char *location)
228 {
229         return addr->ops->create_socket(addr, type, mem_ctx, sock, location);
230 }
231