LCOV - code coverage report
Current view: directory - src/trusted/desc - nacl_desc_conn_cap.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 112 41 36.6 %
Date: 2014-09-25 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2012 The Native Client Authors. All rights reserved.
       3                 :  * Use of this source code is governed by a BSD-style license that can be
       4                 :  * found in the LICENSE file.
       5                 :  */
       6                 : 
       7                 : /*
       8                 :  * NaCl Service Runtime.  I/O Descriptor / Handle abstraction.
       9                 :  * Connection capabilities.
      10                 :  */
      11                 : 
      12                 : #include <stdlib.h>
      13                 : #include <string.h>
      14                 : 
      15                 : #include "native_client/src/include/portability.h"
      16                 : #include "native_client/src/include/nacl_macros.h"
      17                 : 
      18                 : #include "native_client/src/shared/imc/nacl_imc_c.h"
      19                 : #include "native_client/src/shared/platform/nacl_log.h"
      20                 : #include "native_client/src/trusted/desc/nacl_desc_base.h"
      21                 : #include "native_client/src/trusted/desc/nacl_desc_conn_cap.h"
      22                 : #include "native_client/src/trusted/desc/nacl_desc_imc.h"
      23                 : #include "native_client/src/trusted/desc/nacl_desc_imc_bound_desc.h"
      24                 : 
      25                 : #include "native_client/src/trusted/service_runtime/nacl_config.h"
      26                 : #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
      27                 : #include "native_client/src/trusted/service_runtime/include/sys/stat.h"
      28                 : 
      29                 : static struct NaClDescVtbl const kNaClDescConnCapVtbl;  /* fwd */
      30                 : 
      31                 : /*
      32                 :  * NaClDescConnCapSubclassCtor takes a memory region of at least the
      33                 :  * size of a NaClDescConnCap in which construction of
      34                 :  * NaClDescConnCap's superclass has already occurred, and construct
      35                 :  * the remaining members (newly introduced by NaClDescConnCap).  This
      36                 :  * is needed by the *Internalize function.
      37                 :  */
      38                 : static int NaClDescConnCapSubclassCtor(struct NaClDescConnCap         *self,
      39               2 :                                        struct NaClSocketAddress const *nsap) {
      40               2 :   struct NaClDesc *basep = (struct NaClDesc *) self;
      41                 : 
      42               2 :   self->cap = *nsap;
      43               2 :   basep->base.vtbl = (struct NaClRefCountVtbl const *) &kNaClDescConnCapVtbl;
      44               2 :   return 1;
      45               2 : }
      46                 : 
      47                 : int NaClDescConnCapCtor(struct NaClDescConnCap          *self,
      48               2 :                         struct NaClSocketAddress const  *nsap) {
      49               2 :   struct NaClDesc *basep = (struct NaClDesc *) self;
      50                 :   int rv;
      51                 : 
      52               2 :   basep->base.vtbl = (struct NaClRefCountVtbl const *) NULL;
      53               2 :   if (!NaClDescCtor(basep)) {
      54               0 :     return 0;
      55                 :   }
      56               2 :   rv = NaClDescConnCapSubclassCtor(self, nsap);
      57               2 :   if (!rv) {
      58                 :     /* NaClDescConnCap construction failed, still a NaClDesc object */
      59               0 :     (*NACL_VTBL(NaClRefCount, basep)->Dtor)((struct NaClRefCount *) basep);
      60                 :     /* not-an-object; caller frees */
      61                 :   }
      62               2 :   return rv;
      63               2 : }
      64                 : 
      65               0 : static void NaClDescConnCapDtor(struct NaClRefCount *vself) {
      66               0 :   vself->vtbl = (struct NaClRefCountVtbl const *) &kNaClDescVtbl;
      67               0 :   (*vself->vtbl->Dtor)(vself);
      68                 :   return;
      69               0 : }
      70                 : 
      71                 : static int NaClDescConnCapFstat(struct NaClDesc          *vself,
      72               0 :                                 struct nacl_abi_stat     *statbuf) {
      73                 :   UNREFERENCED_PARAMETER(vself);
      74                 : 
      75               0 :   memset(statbuf, 0, sizeof *statbuf);
      76               0 :   statbuf->nacl_abi_st_mode = NACL_ABI_S_IFSOCKADDR | NACL_ABI_S_IRWXU;
      77               0 :   return 0;
      78               0 : }
      79                 : 
      80                 : static int NaClDescConnCapExternalizeSize(struct NaClDesc  *vself,
      81                 :                                           size_t           *nbytes,
      82               0 :                                           size_t           *nhandles) {
      83                 :   int rv;
      84                 : 
      85                 :   UNREFERENCED_PARAMETER(vself);
      86                 : 
      87               0 :   rv = NaClDescExternalizeSize(vself, nbytes, nhandles);
      88               0 :   if (0 != rv) {
      89               0 :     return rv;
      90                 :   }
      91                 : 
      92               0 :   *nbytes += NACL_PATH_MAX;
      93                 : 
      94               0 :   return 0;
      95               0 : }
      96                 : 
      97                 : static int NaClDescConnCapExternalize(struct NaClDesc          *vself,
      98               0 :                                       struct NaClDescXferState *xfer) {
      99                 :   struct NaClDescConnCap *self;
     100                 :   int rv;
     101                 : 
     102               0 :   rv = NaClDescExternalize(vself, xfer);
     103               0 :   if (0 != rv) {
     104               0 :     return rv;
     105                 :   }
     106               0 :   self = (struct NaClDescConnCap *) vself;
     107               0 :   memcpy(xfer->next_byte, self->cap.path, NACL_PATH_MAX);
     108               0 :   xfer->next_byte += NACL_PATH_MAX;
     109                 : 
     110               0 :   return 0;
     111               0 : }
     112                 : 
     113                 : int NaClDescConnCapConnectAddr(struct NaClDesc *vself,
     114               2 :                                struct NaClDesc **out_desc) {
     115                 :   /*
     116                 :    * See NaClDescImcBoundDescAcceptConn code in
     117                 :    * nacl_desc_imc_bound_desc.c
     118                 :    */
     119                 :   struct NaClDescConnCap      *self;
     120                 :   int                         retval;
     121                 :   NaClHandle                  nh[2];
     122                 :   size_t                      ix;
     123                 :   struct NaClMessageHeader    conn_msg;
     124                 :   struct NaClDescImcDesc      *peer;
     125                 : 
     126               2 :   NaClLog(3, "Entered NaClDescConnCapConnectAddr\n");
     127               2 :   self = (struct NaClDescConnCap *) vself;
     128                 : 
     129               2 :   peer = NULL;
     130               2 :   for (ix = 0; ix < NACL_ARRAY_SIZE(nh); ++ix) {
     131               2 :     nh[ix] = NACL_INVALID_HANDLE;
     132               2 :   }
     133                 : 
     134               2 :   NaClLog(4, " socket address %.*s\n", NACL_PATH_MAX, self->cap.path);
     135                 : 
     136               2 :   if (NULL == (peer = malloc(sizeof *peer))) {
     137               0 :     retval = -NACL_ABI_ENOMEM;
     138               0 :     goto cleanup;
     139                 :   }
     140                 : 
     141               2 :   if (0 != NaClSocketPair(nh)) {
     142               0 :     retval = -NACL_ABI_EMFILE;
     143               0 :     goto cleanup;
     144                 :   }
     145                 : 
     146               2 :   conn_msg.iov_length = 0;
     147               2 :   conn_msg.iov = NULL;
     148               2 :   conn_msg.handles = &nh[0];
     149               2 :   conn_msg.handle_count = 1;  /* send nh[0], keep nh[1] */
     150               2 :   conn_msg.flags = 0;
     151                 : 
     152               2 :   NaClLog(4, " sending connection message\n");
     153               2 :   if (-1 == NaClSendDatagramTo(&conn_msg, 0, &self->cap)) {
     154                 :     NaClLog(LOG_ERROR, ("NaClDescConnCapConnectAddr:"
     155               0 :                         " initial connect message could not be sent.\n"));
     156               0 :     retval = -NACL_ABI_EIO;
     157               0 :     goto cleanup;
     158                 :   }
     159                 : 
     160               2 :   (void) NaClClose(nh[0]);
     161               2 :   nh[0] = NACL_INVALID_HANDLE;
     162               2 :   NaClLog(4, " creating NaClDescImcDesc for local end of socketpair\n");
     163               2 :   if (!NaClDescImcDescCtor(peer, nh[1])) {
     164               0 :     retval = -NACL_ABI_EMFILE;  /* TODO(bsy): is this the right errno? */
     165               0 :     goto cleanup;
     166                 :   }
     167               2 :   nh[1] = NACL_INVALID_HANDLE;
     168                 : 
     169               2 :   *out_desc = (struct NaClDesc *) peer;
     170               2 :   retval = 0;
     171                 : 
     172                 : cleanup:
     173               2 :   if (retval < 0) {
     174               0 :     NaClLog(4, " error return; cleaning up\n");
     175               0 :     if (NACL_INVALID_HANDLE != nh[0])
     176               0 :       (void) NaClClose(nh[0]);
     177               0 :     if (NACL_INVALID_HANDLE != nh[1])
     178               0 :       (void) NaClClose(nh[1]);
     179                 :     /* peer is not constructed, so we need only to free the memory */
     180               0 :     free(peer);
     181                 :   }
     182               2 :   return retval;
     183               2 : }
     184                 : 
     185                 : static int NaClDescConnCapAcceptConn(struct NaClDesc *vself,
     186               0 :                                      struct NaClDesc **out_desc) {
     187                 :   UNREFERENCED_PARAMETER(vself);
     188                 :   UNREFERENCED_PARAMETER(out_desc);
     189                 : 
     190               0 :   NaClLog(LOG_ERROR, "NaClDescConnCapAcceptConn: not IMC\n");
     191               0 :   return -NACL_ABI_EINVAL;
     192               0 : }
     193                 : 
     194                 : static struct NaClDescVtbl const kNaClDescConnCapVtbl = {
     195                 :   {
     196                 :     NaClDescConnCapDtor,
     197                 :   },
     198                 :   NaClDescMapNotImplemented,
     199                 :   NACL_DESC_UNMAP_NOT_IMPLEMENTED
     200                 :   NaClDescReadNotImplemented,
     201                 :   NaClDescWriteNotImplemented,
     202                 :   NaClDescSeekNotImplemented,
     203                 :   NaClDescPReadNotImplemented,
     204                 :   NaClDescPWriteNotImplemented,
     205                 :   NaClDescConnCapFstat,
     206                 :   NaClDescGetdentsNotImplemented,
     207                 :   NaClDescConnCapExternalizeSize,
     208                 :   NaClDescConnCapExternalize,
     209                 :   NaClDescLockNotImplemented,
     210                 :   NaClDescTryLockNotImplemented,
     211                 :   NaClDescUnlockNotImplemented,
     212                 :   NaClDescWaitNotImplemented,
     213                 :   NaClDescTimedWaitAbsNotImplemented,
     214                 :   NaClDescSignalNotImplemented,
     215                 :   NaClDescBroadcastNotImplemented,
     216                 :   NaClDescSendMsgNotImplemented,
     217                 :   NaClDescRecvMsgNotImplemented,
     218                 :   NaClDescLowLevelSendMsgNotImplemented,
     219                 :   NaClDescLowLevelRecvMsgNotImplemented,
     220                 :   NaClDescConnCapConnectAddr,
     221                 :   NaClDescConnCapAcceptConn,
     222                 :   NaClDescPostNotImplemented,
     223                 :   NaClDescSemWaitNotImplemented,
     224                 :   NaClDescGetValueNotImplemented,
     225                 :   NaClDescSetMetadata,
     226                 :   NaClDescGetMetadata,
     227                 :   NaClDescSetFlags,
     228                 :   NaClDescGetFlags,
     229                 :   NaClDescIsattyNotImplemented,
     230                 :   NACL_DESC_CONN_CAP,
     231                 : };
     232                 : 
     233                 : int NaClDescConnCapInternalize(struct NaClDesc               **out_desc,
     234                 :                                struct NaClDescXferState      *xfer,
     235               0 :                                struct NaClDescQuotaInterface *quota_interface) {
     236                 :   int                       rv;
     237                 :   struct NaClSocketAddress  nsa;
     238                 :   struct NaClDescConnCap    *ndccp;
     239                 : 
     240                 :   UNREFERENCED_PARAMETER(quota_interface);
     241               0 :   rv = -NACL_ABI_EIO;  /* catch-all */
     242                 : 
     243               0 :   ndccp = malloc(sizeof *ndccp);
     244               0 :   if (NULL == ndccp) {
     245               0 :     rv = -NACL_ABI_ENOMEM;
     246               0 :     goto cleanup;
     247                 :   }
     248               0 :   if (!NaClDescInternalizeCtor((struct NaClDesc *) ndccp, xfer)) {
     249               0 :     free(ndccp);
     250               0 :     ndccp = NULL;
     251               0 :     rv = -NACL_ABI_ENOMEM;
     252               0 :     goto cleanup;
     253                 :   }
     254               0 :   if (xfer->next_byte + NACL_PATH_MAX > xfer->byte_buffer_end) {
     255               0 :     rv = -NACL_ABI_EIO;
     256               0 :     goto cleanup;
     257                 :   }
     258               0 :   memcpy(nsa.path, xfer->next_byte, NACL_PATH_MAX);
     259               0 :   if (!NaClDescConnCapSubclassCtor(ndccp, &nsa)) {
     260               0 :     rv = -NACL_ABI_EIO;
     261               0 :     goto cleanup;
     262                 :   }
     263               0 :   *out_desc = (struct NaClDesc *) ndccp;
     264               0 :   rv = 0;
     265               0 :   xfer->next_byte += NACL_PATH_MAX;
     266                 : cleanup:
     267               0 :   if (rv < 0) {
     268               0 :     NaClDescSafeUnref((struct NaClDesc *) ndccp);
     269                 :   }
     270               0 :   return rv;
     271               0 : }

Generated by: LCOV version 1.7