root/source3/rpc_client/rpc_transport_sock.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rpc_transport_sock_state_destructor
  2. rpc_sock_read_send
  3. rpc_sock_read_done
  4. rpc_sock_read_recv
  5. rpc_sock_write_send
  6. rpc_sock_write_done
  7. rpc_sock_write_recv
  8. rpc_transport_sock_init
  9. rpccli_set_sock_timeout
  10. rpccli_close_sock_fd
  11. rpc_pipe_tcp_connection_ok

   1 /*
   2  *  Unix SMB/CIFS implementation.
   3  *  RPC client transport over a socket
   4  *  Copyright (C) Volker Lendecke 2009
   5  *
   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.
  10  *
  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.
  15  *
  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/>.
  18  */
  19 
  20 #include "includes.h"
  21 
  22 #undef DBGC_CLASS
  23 #define DBGC_CLASS DBGC_RPC_CLI
  24 
  25 struct rpc_transport_sock_state {
  26         int fd;
  27         int timeout;
  28 };
  29 
  30 static int rpc_transport_sock_state_destructor(struct rpc_transport_sock_state *s)
     /* [<][>][^][v][top][bottom][index][help] */
  31 {
  32         if (s->fd != -1) {
  33                 close(s->fd);
  34                 s->fd = -1;
  35         }
  36         return 0;
  37 }
  38 
  39 struct rpc_sock_read_state {
  40         ssize_t received;
  41 };
  42 
  43 static void rpc_sock_read_done(struct tevent_req *subreq);
  44 
  45 static struct async_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
  46                                             struct event_context *ev,
  47                                             uint8_t *data, size_t size,
  48                                             void *priv)
  49 {
  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;
  55         struct timeval endtime;
  56 
  57         if (!async_req_setup(mem_ctx, &result, &state,
  58                              struct rpc_sock_read_state)) {
  59                 return NULL;
  60         }
  61 
  62         endtime = timeval_current_ofs(0, sock_transp->timeout * 1000);
  63         subreq = async_recv_send(state, ev, sock_transp->fd, data, size, 0);
  64         if (subreq == NULL) {
  65                 goto fail;
  66         }
  67  
  68         if (!tevent_req_set_endtime(subreq, ev, endtime)) {
  69                 goto fail;
  70         }
  71  
  72         tevent_req_set_callback(subreq, rpc_sock_read_done, result);
  73         return result;
  74  fail:
  75         TALLOC_FREE(result);
  76         return NULL;
  77 }
  78 
  79 static void rpc_sock_read_done(struct tevent_req *subreq)
     /* [<][>][^][v][top][bottom][index][help] */
  80 {
  81         struct async_req *req =
  82                 tevent_req_callback_data(subreq, struct async_req);
  83         struct rpc_sock_read_state *state = talloc_get_type_abort(
  84                 req->private_data, struct rpc_sock_read_state);
  85         int err;
  86 
  87         state->received = async_recv_recv(subreq, &err);
  88         if (state->received == -1) {
  89                 async_req_nterror(req, map_nt_error_from_unix(err));
  90                 return;
  91         }
  92         async_req_done(req);
  93 }
  94 
  95 static NTSTATUS rpc_sock_read_recv(struct async_req *req, ssize_t *preceived)
     /* [<][>][^][v][top][bottom][index][help] */
  96 {
  97         struct rpc_sock_read_state *state = talloc_get_type_abort(
  98                 req->private_data, struct rpc_sock_read_state);
  99         NTSTATUS status;
 100 
 101         if (async_req_is_nterror(req, &status)) {
 102                 return status;
 103         }
 104         *preceived = state->received;
 105         return NT_STATUS_OK;
 106 }
 107 
 108 struct rpc_sock_write_state {
 109         ssize_t sent;
 110 };
 111 
 112 static void rpc_sock_write_done(struct tevent_req *subreq);
 113 
 114 static struct async_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 115                                              struct event_context *ev,
 116                                              const uint8_t *data, size_t size,
 117                                              void *priv)
 118 {
 119         struct rpc_transport_sock_state *sock_transp = talloc_get_type_abort(
 120                 priv, struct rpc_transport_sock_state);
 121         struct async_req *result;
 122         struct tevent_req *subreq;
 123         struct rpc_sock_write_state *state;
 124         struct timeval endtime;
 125 
 126         if (!async_req_setup(mem_ctx, &result, &state,
 127                              struct rpc_sock_write_state)) {
 128                 return NULL;
 129         }
 130         endtime = timeval_current_ofs(0, sock_transp->timeout * 1000);
 131         subreq = async_send_send(state, ev, sock_transp->fd, data, size, 0);
 132         if (subreq == NULL) {
 133                 goto fail;
 134         }
 135  
 136         if (!tevent_req_set_endtime(subreq, ev, endtime)) {
 137                 goto fail;
 138         }
 139  
 140         tevent_req_set_callback(subreq, rpc_sock_write_done, result);
 141         return result;
 142  fail:
 143         TALLOC_FREE(result);
 144         return NULL;
 145 }
 146 
 147 static void rpc_sock_write_done(struct tevent_req *subreq)
     /* [<][>][^][v][top][bottom][index][help] */
 148 {
 149         struct async_req *req =
 150                 tevent_req_callback_data(subreq, struct async_req);
 151         struct rpc_sock_write_state *state = talloc_get_type_abort(
 152                 req->private_data, struct rpc_sock_write_state);
 153         int err;
 154 
 155         state->sent = async_send_recv(subreq, &err);
 156         if (state->sent == -1) {
 157                 async_req_nterror(req, map_nt_error_from_unix(err));
 158                 return;
 159         }
 160         async_req_done(req);
 161 }
 162 
 163 static NTSTATUS rpc_sock_write_recv(struct async_req *req, ssize_t *psent)
     /* [<][>][^][v][top][bottom][index][help] */
 164 {
 165         struct rpc_sock_write_state *state = talloc_get_type_abort(
 166                 req->private_data, struct rpc_sock_write_state);
 167         NTSTATUS status;
 168 
 169         if (async_req_is_nterror(req, &status)) {
 170                 return status;
 171         }
 172         *psent = state->sent;
 173         return NT_STATUS_OK;
 174 }
 175 
 176 NTSTATUS rpc_transport_sock_init(TALLOC_CTX *mem_ctx, int fd,
     /* [<][>][^][v][top][bottom][index][help] */
 177                                  struct rpc_cli_transport **presult)
 178 {
 179         struct rpc_cli_transport *result;
 180         struct rpc_transport_sock_state *state;
 181 
 182         result = talloc(mem_ctx, struct rpc_cli_transport);
 183         if (result == NULL) {
 184                 return NT_STATUS_NO_MEMORY;
 185         }
 186         state = talloc(result, struct rpc_transport_sock_state);
 187         if (state == NULL) {
 188                 TALLOC_FREE(result);
 189                 return NT_STATUS_NO_MEMORY;
 190         }
 191         result->priv = state;
 192 
 193         state->fd = fd;
 194         state->timeout = 10000; /* 10 seconds. */
 195         talloc_set_destructor(state, rpc_transport_sock_state_destructor);
 196 
 197         result->trans_send = NULL;
 198         result->trans_recv = NULL;
 199         result->write_send = rpc_sock_write_send;
 200         result->write_recv = rpc_sock_write_recv;
 201         result->read_send = rpc_sock_read_send;
 202         result->read_recv = rpc_sock_read_recv;
 203 
 204         *presult = result;
 205         return NT_STATUS_OK;
 206 }
 207 
 208 int rpccli_set_sock_timeout(struct rpc_pipe_client *cli, int timeout)
     /* [<][>][^][v][top][bottom][index][help] */
 209 {
 210         struct rpc_transport_sock_state *state = talloc_get_type(cli->transport->priv,
 211                                                         struct rpc_transport_sock_state);
 212         int orig_timeout;
 213         if (!state) {
 214                 return 0;
 215         }
 216         orig_timeout = state->timeout;
 217         state->timeout = timeout;
 218         return orig_timeout;
 219 }
 220 
 221 void rpccli_close_sock_fd(struct rpc_pipe_client *cli)
     /* [<][>][^][v][top][bottom][index][help] */
 222 {
 223         struct rpc_transport_sock_state *state = talloc_get_type(cli->transport->priv,
 224                                                         struct rpc_transport_sock_state);
 225         if (state) {
 226                 if (state->fd != -1) {
 227                         close(state->fd);
 228                         state->fd = -1;
 229                 }
 230         }
 231         return;
 232 }
 233 
 234 bool rpc_pipe_tcp_connection_ok(struct rpc_pipe_client *cli)
     /* [<][>][^][v][top][bottom][index][help] */
 235 {
 236         struct rpc_transport_sock_state *state = talloc_get_type(cli->transport->priv,
 237                                                         struct rpc_transport_sock_state);
 238         if (state && state->fd != -1) {
 239                 return true;
 240         }
 241 
 242         return false;
 243 }

/* [<][>][^][v][top][bottom][index][help] */