2 * Copyright 2008, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * NaCl Service Runtime. I/O Descriptor / Handle abstraction.
34 * Connection capabilities.
40 #include "native_client/include/portability.h"
42 #include "native_client/service_runtime/nacl_config.h"
43 #include "native_client/service_runtime/nacl_log.h"
44 #include "native_client/service_runtime/nacl_desc_base.h"
45 #include "native_client/service_runtime/nacl_desc_imc.h"
47 #include "native_client/service_runtime/include/sys/errno.h"
49 #include "native_client/intermodule_comm/nacl_imc_c.h"
51 int NaClDescConnCapCtor(struct NaClDescConnCap
*self
,
52 struct NaClSocketAddress
const *nsap
)
54 struct NaClDesc
*basep
= (struct NaClDesc
*) self
;
56 basep
->vtbl
= (struct NaClDescVtbl
*) NULL
;
57 if (!NaClDescCtor(basep
)) {
61 basep
->vtbl
= &kNaClDescConnCapVtbl
;
65 void NaClDescConnCapDtor(struct NaClDesc
*vself
)
67 vself
->vtbl
= (struct NaClDescVtbl
*) NULL
;
72 int NaClDescConnCapClose(struct NaClDesc
*vself
,
73 struct NaClDescEffector
*effp
)
79 int NaClDescConnCapExternalizeSize(struct NaClDesc
*vself
,
83 *nbytes
= NACL_PATH_MAX
;
89 int NaClDescConnCapExternalize(struct NaClDesc
*vself
,
90 struct NaClDescXferState
*xfer
)
92 struct NaClDescConnCap
*self
;
94 self
= (struct NaClDescConnCap
*) vself
;
95 memcpy(xfer
->next_byte
, self
->cap
.path
, NACL_PATH_MAX
);
96 xfer
->next_byte
+= NACL_PATH_MAX
;
101 int NaClDescConnCapConnectAddr(struct NaClDesc
*vself
,
102 struct NaClDescEffector
*effp
)
105 * See NaClDescImcBoundDescAcceptConn code in
106 * nacl_desc_imc_bound_desc.c
108 struct NaClDescConnCap
*self
;
109 struct NaClDescImcBoundDesc
*sender
;
112 struct NaClMessageHeader conn_msg
;
113 struct NaClDescImcDesc
*peer
;
115 NaClLog(3, "Entered NaClDescConnCapConnectAddr\n");
116 self
= (struct NaClDescConnCap
*) vself
;
118 sender
= (*effp
->vtbl
->SourceSock
)(effp
);
119 if (NULL
== sender
) {
120 NaClLog(LOG_ERROR
, "NaClDescConnCapConnectAddr: service socket NULL\n");
121 return -NACL_ABI_EIO
;
124 NaClLog(4, " socket address %.*s\n", NACL_PATH_MAX
, self
->cap
.path
);
126 if (NULL
== (peer
= malloc(sizeof *peer
))) {
127 return -NACL_ABI_ENOMEM
;
130 if (0 != NaClSocketPair(nh
)) {
131 return -NACL_ABI_EMFILE
;
134 conn_msg
.iov_length
= 0;
135 conn_msg
.handles
= &nh
[0];
136 conn_msg
.handle_count
= 1; /* send nh[0], keep nh[1] */
139 NaClLog(4, " sending connection message\n");
140 if (-1 == NaClSendDatagramTo(sender
->h
,
144 NaClLog(LOG_ERROR
, ("NaClDescConnCapConnectAddr:"
145 " initial connect message could not be sent.\n"));
146 retval
= -NACL_ABI_EMFILE
;
150 (void) NaClClose(nh
[0]);
151 nh
[0] = NACL_INVALID_HANDLE
;
152 NaClLog(4, " creating NaClDescImcDesc for local end of socketpair\n");
153 if (!NaClDescImcDescCtor(peer
, nh
[1])) {
154 retval
= -NACL_ABI_EMFILE
; /* TODO: is this the right errno? */
157 nh
[1] = NACL_INVALID_HANDLE
;
159 retval
= (*effp
->vtbl
->ReturnCreatedDesc
)(effp
, ((struct NaClDesc
*) peer
));
163 NaClLog(4, " error return; cleaning up\n");
164 if (NACL_INVALID_HANDLE
!= nh
[0])
165 (void) NaClClose(nh
[0]);
166 if (NACL_INVALID_HANDLE
!= nh
[1])
167 (void) NaClClose(nh
[1]);
168 /* peer is not constructed, so we need only to free the memory */
174 int NaClDescConnCapAcceptConn(struct NaClDesc
*vself
,
175 struct NaClDescEffector
*effp
)
177 NaClLog(LOG_ERROR
, "NaClDescConnCapAcceptConn: not IMC\n");
178 return -NACL_ABI_EINVAL
;
181 struct NaClDescVtbl
const kNaClDescConnCapVtbl
= {
183 NaClDescMapNotImplemented
,
184 NaClDescUnmapUnsafeNotImplemented
,
185 NaClDescUnmapNotImplemented
,
186 NaClDescReadNotImplemented
,
187 NaClDescWriteNotImplemented
,
188 NaClDescSeekNotImplemented
,
189 NaClDescIoctlNotImplemented
,
190 NaClDescFstatNotImplemented
,
191 NaClDescConnCapClose
,
192 NaClDescGetdentsNotImplemented
,
194 NaClDescConnCapExternalizeSize
,
195 NaClDescConnCapExternalize
,
196 NaClDescLockNotImplemented
,
197 NaClDescTryLockNotImplemented
,
198 NaClDescUnlockNotImplemented
,
199 NaClDescWaitNotImplemented
,
200 NaClDescTimedWaitAbsNotImplemented
,
201 NaClDescSignalNotImplemented
,
202 NaClDescBroadcastNotImplemented
,
203 NaClDescSendMsgNotImplemented
,
204 NaClDescRecvMsgNotImplemented
,
205 NaClDescConnCapConnectAddr
,
206 NaClDescConnCapAcceptConn
,
207 NaClDescPostNotImplemented
,
208 NaClDescSemWaitNotImplemented
,
209 NaClDescGetValueNotImplemented
,
212 int NaClDescConnCapInternalize(struct NaClDesc
**baseptr
,
213 struct NaClDescXferState
*xfer
)
216 struct NaClSocketAddress nsa
;
217 struct NaClDescConnCap
*ndccp
;
219 rv
= -NACL_ABI_EIO
; /* catch-all */
222 if (xfer
->next_byte
+ NACL_PATH_MAX
> xfer
->byte_buffer_end
) {
226 memcpy(nsa
.path
, xfer
->next_byte
, NACL_PATH_MAX
);
227 ndccp
= malloc(sizeof *ndccp
);
229 rv
= -NACL_ABI_ENOMEM
;
232 if (!NaClDescConnCapCtor(ndccp
, &nsa
)) {
233 rv
= -NACL_ABI_ENOMEM
;
236 *baseptr
= (struct NaClDesc
*) ndccp
;
238 xfer
->next_byte
+= NACL_PATH_MAX
;