2 Unix SMB/CIFS implementation.
4 Copyright (C) Stefan Metzmacher 2009
6 ** NOTE! The following LGPL license applies to the tevent
7 ** library. This does NOT imply that all of Samba is released
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.
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.
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/>.
25 #include "system/network.h"
27 #include "tsocket_internal.h"
29 struct tsocket_sendto_state
{
30 /* this structs are owned by the caller */
32 struct tsocket_context
*sock
;
35 const struct tsocket_address
*dst
;
41 static int tsocket_sendto_state_destructor(struct tsocket_sendto_state
*state
)
43 if (state
->caller
.sock
) {
44 tsocket_set_writeable_handler(state
->caller
.sock
, NULL
, NULL
);
46 ZERO_STRUCT(state
->caller
);
51 static void tsocket_sendto_handler(struct tsocket_context
*sock
,
54 struct tevent_req
*tsocket_sendto_send(struct tsocket_context
*sock
,
58 const struct tsocket_address
*dst
)
60 struct tevent_req
*req
;
61 struct tsocket_sendto_state
*state
;
66 req
= tevent_req_create(mem_ctx
, &state
,
67 struct tsocket_sendto_state
);
72 state
->caller
.sock
= sock
;
73 state
->caller
.buf
= buf
;
74 state
->caller
.len
= len
;
75 state
->caller
.dst
= dst
;
78 talloc_set_destructor(state
, tsocket_sendto_state_destructor
);
80 ret
= tsocket_set_writeable_handler(sock
,
81 tsocket_sendto_handler
,
83 err
= tsocket_error_from_errno(ret
, errno
, &dummy
);
84 if (tevent_req_error(req
, err
)) {
91 return tevent_req_post(req
, sock
->event
.ctx
);
94 static void tsocket_sendto_handler(struct tsocket_context
*sock
,
97 struct tevent_req
*req
= talloc_get_type(private_data
,
99 struct tsocket_sendto_state
*state
= tevent_req_data(req
,
100 struct tsocket_sendto_state
);
105 ret
= tsocket_sendto(state
->caller
.sock
,
109 err
= tsocket_error_from_errno(ret
, errno
, &retry
);
114 if (tevent_req_error(req
, err
)) {
120 tevent_req_done(req
);
123 ssize_t
tsocket_sendto_recv(struct tevent_req
*req
, int *perrno
)
125 struct tsocket_sendto_state
*state
= tevent_req_data(req
,
126 struct tsocket_sendto_state
);
129 ret
= tsocket_simple_int_recv(req
, perrno
);
134 tevent_req_received(req
);
138 struct tsocket_sendto_queue_state
{
139 /* this structs are owned by the caller */
141 struct tsocket_context
*sock
;
144 const struct tsocket_address
*dst
;
149 static void tsocket_sendto_queue_trigger(struct tevent_req
*req
,
151 static void tsocket_sendto_queue_done(struct tevent_req
*subreq
);
154 * @brief Queue a dgram blob for sending through the socket
155 * @param[in] mem_ctx The memory context for the result
156 * @param[in] sock The socket to send the message buffer
157 * @param[in] queue The existing dgram queue
158 * @param[in] buf The message buffer
159 * @param[in] len The message length
160 * @param[in] dst The destination socket address
161 * @retval The async request handle
163 * This function queues a blob for sending to destination through an existing
164 * dgram socket. The async callback is triggered when the whole blob is
165 * delivered to the underlying system socket.
167 * The caller needs to make sure that all non-scalar input parameters hang
168 * arround for the whole lifetime of the request.
170 struct tevent_req
*tsocket_sendto_queue_send(TALLOC_CTX
*mem_ctx
,
171 struct tsocket_context
*sock
,
172 struct tevent_queue
*queue
,
175 struct tsocket_address
*dst
)
177 struct tevent_req
*req
;
178 struct tsocket_sendto_queue_state
*state
;
181 req
= tevent_req_create(mem_ctx
, &state
,
182 struct tsocket_sendto_queue_state
);
187 state
->caller
.sock
= sock
;
188 state
->caller
.buf
= buf
;
189 state
->caller
.len
= len
;
190 state
->caller
.dst
= dst
;
193 ok
= tevent_queue_add(queue
,
196 tsocket_sendto_queue_trigger
,
199 tevent_req_nomem(NULL
, req
);
206 return tevent_req_post(req
, sock
->event
.ctx
);
209 static void tsocket_sendto_queue_trigger(struct tevent_req
*req
,
212 struct tsocket_sendto_queue_state
*state
= tevent_req_data(req
,
213 struct tsocket_sendto_queue_state
);
214 struct tevent_req
*subreq
;
216 subreq
= tsocket_sendto_send(state
->caller
.sock
,
221 if (tevent_req_nomem(subreq
, req
)) {
224 tevent_req_set_callback(subreq
, tsocket_sendto_queue_done
,req
);
227 static void tsocket_sendto_queue_done(struct tevent_req
*subreq
)
229 struct tevent_req
*req
= tevent_req_callback_data(subreq
,
231 struct tsocket_sendto_queue_state
*state
= tevent_req_data(req
,
232 struct tsocket_sendto_queue_state
);
236 ret
= tsocket_sendto_recv(subreq
, &sys_errno
);
239 tevent_req_error(req
, sys_errno
);
244 tevent_req_done(req
);
247 ssize_t
tsocket_sendto_queue_recv(struct tevent_req
*req
, int *perrno
)
249 struct tsocket_sendto_queue_state
*state
= tevent_req_data(req
,
250 struct tsocket_sendto_queue_state
);
253 ret
= tsocket_simple_int_recv(req
, perrno
);
258 tevent_req_received(req
);