2 * Unix SMB/CIFS implementation.
3 * RPC client transport over a socket
4 * Copyright (C) Volker Lendecke 2009
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
23 #define DBGC_CLASS DBGC_RPC_CLI
25 struct rpc_transport_sock_state
{
29 static int rpc_transport_sock_state_destructor(struct rpc_transport_sock_state
*s
)
38 struct rpc_sock_read_state
{
39 struct rpc_transport_sock_state
*transp
;
43 static void rpc_sock_read_done(struct tevent_req
*subreq
);
45 static struct async_req
*rpc_sock_read_send(TALLOC_CTX
*mem_ctx
,
46 struct event_context
*ev
,
47 uint8_t *data
, size_t size
,
50 struct rpc_transport_sock_state
*sock_transp
= talloc_get_type_abort(
51 priv
, struct rpc_transport_sock_state
);
52 struct async_req
*result
;
53 struct tevent_req
*subreq
;
54 struct rpc_sock_read_state
*state
;
56 if (!async_req_setup(mem_ctx
, &result
, &state
,
57 struct rpc_sock_read_state
)) {
60 if (sock_transp
->fd
== -1) {
61 if (!async_post_ntstatus(result
, ev
, NT_STATUS_CONNECTION_INVALID
)) {
66 state
->transp
= sock_transp
;
67 subreq
= async_recv_send(state
, ev
, sock_transp
->fd
, data
, size
, 0);
71 tevent_req_set_callback(subreq
, rpc_sock_read_done
, result
);
78 static void rpc_sock_read_done(struct tevent_req
*subreq
)
80 struct async_req
*req
=
81 tevent_req_callback_data(subreq
, struct async_req
);
82 struct rpc_sock_read_state
*state
= talloc_get_type_abort(
83 req
->private_data
, struct rpc_sock_read_state
);
86 /* We must free subreq in this function as there is
87 a timer event attached to it. */
89 state
->received
= async_recv_recv(subreq
, &err
);
91 if (state
->received
== -1) {
93 close(state
->transp
->fd
);
94 state
->transp
->fd
= -1;
97 async_req_nterror(req
, map_nt_error_from_unix(err
));
104 static NTSTATUS
rpc_sock_read_recv(struct async_req
*req
, ssize_t
*preceived
)
106 struct rpc_sock_read_state
*state
= talloc_get_type_abort(
107 req
->private_data
, struct rpc_sock_read_state
);
110 if (async_req_is_nterror(req
, &status
)) {
113 *preceived
= state
->received
;
117 struct rpc_sock_write_state
{
118 struct rpc_transport_sock_state
*transp
;
122 static void rpc_sock_write_done(struct tevent_req
*subreq
);
124 static struct async_req
*rpc_sock_write_send(TALLOC_CTX
*mem_ctx
,
125 struct event_context
*ev
,
126 const uint8_t *data
, size_t size
,
129 struct rpc_transport_sock_state
*sock_transp
= talloc_get_type_abort(
130 priv
, struct rpc_transport_sock_state
);
131 struct async_req
*result
;
132 struct tevent_req
*subreq
;
133 struct rpc_sock_write_state
*state
;
135 if (!async_req_setup(mem_ctx
, &result
, &state
,
136 struct rpc_sock_write_state
)) {
139 if (sock_transp
->fd
== -1) {
140 if (!async_post_ntstatus(result
, ev
, NT_STATUS_CONNECTION_INVALID
)) {
145 state
->transp
= sock_transp
;
146 subreq
= async_send_send(state
, ev
, sock_transp
->fd
, data
, size
, 0);
147 if (subreq
== NULL
) {
150 tevent_req_set_callback(subreq
, rpc_sock_write_done
, result
);
157 static void rpc_sock_write_done(struct tevent_req
*subreq
)
159 struct async_req
*req
=
160 tevent_req_callback_data(subreq
, struct async_req
);
161 struct rpc_sock_write_state
*state
= talloc_get_type_abort(
162 req
->private_data
, struct rpc_sock_write_state
);
165 /* We must free subreq in this function as there is
166 a timer event attached to it. */
168 state
->sent
= async_send_recv(subreq
, &err
);
170 if (state
->sent
== -1) {
172 close(state
->transp
->fd
);
173 state
->transp
->fd
= -1;
176 async_req_nterror(req
, map_nt_error_from_unix(err
));
183 static NTSTATUS
rpc_sock_write_recv(struct async_req
*req
, ssize_t
*psent
)
185 struct rpc_sock_write_state
*state
= talloc_get_type_abort(
186 req
->private_data
, struct rpc_sock_write_state
);
189 if (async_req_is_nterror(req
, &status
)) {
192 *psent
= state
->sent
;
196 NTSTATUS
rpc_transport_sock_init(TALLOC_CTX
*mem_ctx
, int fd
,
197 struct rpc_cli_transport
**presult
)
199 struct rpc_cli_transport
*result
;
200 struct rpc_transport_sock_state
*state
;
202 result
= talloc(mem_ctx
, struct rpc_cli_transport
);
203 if (result
== NULL
) {
204 return NT_STATUS_NO_MEMORY
;
206 state
= talloc(result
, struct rpc_transport_sock_state
);
209 return NT_STATUS_NO_MEMORY
;
211 result
->priv
= state
;
214 talloc_set_destructor(state
, rpc_transport_sock_state_destructor
);
216 result
->trans_send
= NULL
;
217 result
->trans_recv
= NULL
;
218 result
->write_send
= rpc_sock_write_send
;
219 result
->write_recv
= rpc_sock_write_recv
;
220 result
->read_send
= rpc_sock_read_send
;
221 result
->read_recv
= rpc_sock_read_recv
;