195
195
THREAD_EXIT(NULL);
200
tcsd_thread_run(void *v)
202
struct tcsd_thread_data *data = (struct tcsd_thread_data *)v;
203
BYTE buffer[TCSD_TXBUF_SIZE];
204
struct tcsd_packet_hdr *ret_buf = NULL;
206
int sizeToSend, sent_total, sent;
208
#ifndef TCSD_SINGLE_THREAD_DEBUG
211
thread_signal_init();
214
if ((data->buf_size = recv(data->sock, buffer, TCSD_TXBUF_SIZE, 0)) < 0) {
215
LogError("Failed Receive: %s", strerror(errno));
218
LogDebug("Rx'd packet");
224
if (data->buf_size > TCSD_TXBUF_SIZE) {
225
LogError("Packet received from socket %d was too large (%u bytes)",
226
data->sock, data->buf_size);
228
} else if (data->buf_size < (int)((2 * sizeof(UINT32)) + sizeof(UINT16))) {
229
LogError("Packet received from socket %d was too small (%u bytes)",
230
data->sock, data->buf_size);
234
if ((result = getTCSDPacket(data, &ret_buf)) != TSS_SUCCESS) {
235
/* something internal to the TCSD went wrong in preparing the packet
236
* to return to the TSP. Use our already allocated buffer to return a
237
* TSS_E_INTERNAL_ERROR return code to the TSP. In the non-error path,
238
* these LoadBlob's are done in getTCSDPacket().
242
LoadBlob_UINT32(&offset, result, buffer);
243
/* load packet size */
244
LoadBlob_UINT32(&offset, sizeof(struct tcsd_packet_hdr), buffer);
246
LoadBlob_UINT16(&offset, 0, buffer);
248
sizeToSend = sizeof(struct tcsd_packet_hdr);
249
LogDebug("Sending 0x%X bytes back", sizeToSend);
251
while (sent_total < sizeToSend) {
252
if ((sent = send(data->sock,
253
&data->buf[sent_total],
254
sizeToSend - sent_total, 0)) < 0) {
255
LogError("Packet send to TSP failed: send: %s. Thread exiting.",
262
sizeToSend = Decode_UINT32((BYTE *)&(ret_buf->packet_size));
264
LogDebug("Sending 0x%X bytes back", sizeToSend);
266
while (sent_total < sizeToSend) {
267
if ((sent = send(data->sock,
268
&(((BYTE *)ret_buf)[sent_total]),
269
sizeToSend - sent_total, 0)) < 0) {
270
LogError("response to TSP failed: send: %s. Thread exiting.",
283
LogDebug("Thread %zd exiting via shutdown signal!", THREAD_ID);
287
/* receive the next packet */
288
if ((data->buf_size = recv(data->sock, buffer, TCSD_TXBUF_SIZE, 0)) < 0) {
289
LogError("TSP has closed its connection: %s. Thread exiting.",
292
} else if (data->buf_size == 0) {
293
LogDebug("The TSP has closed the socket's connection. Thread exiting.");
299
/* Closing connection to TSP */
304
/* If the connection was not shut down cleanly, free TCS resources here */
305
if (data->context != NULL_TCS_HANDLE) {
306
TCS_CloseContext_Internal(data->context);
307
data->context = NULL_TCS_HANDLE;
310
#ifndef TCSD_SINGLE_THREAD_DEBUG
311
MUTEX_LOCK(tm->lock);
312
tm->num_active_threads--;
313
/* if we're not in shutdown mode, then nobody is waiting to join this thread, so
314
* detach it so that its resources are free at THREAD_EXIT() time. */
316
if ((rc = THREAD_DETACH(*(data->thread_id)))) {
317
LogError("Thread detach failed (errno %d)."
318
" Resources may not be properly released.", rc);
321
free(data->hostname);
322
data->hostname = NULL;
323
data->thread_id = THREAD_NULL;
324
MUTEX_UNLOCK(tm->lock);
332
200
tcsd_thread_run(void *v)
334
202
struct tcsd_thread_data *data = (struct tcsd_thread_data *)v;
336
int recv_size, send_size;
204
int recd_so_far, empty_space, total_recv_size, recv_chunk_size, send_size;
337
205
TSS_RESULT result;
339
207
#ifndef TCSD_SINGLE_THREAD_DEBUG
346
214
data->comm.buf = calloc(1, data->comm.buf_size);
347
215
while (data->comm.buf) {
348
216
/* get the packet header to get the size of the incoming packet */
349
buffer = data->comm.buf;
350
recv_size = sizeof(struct tcsd_packet_hdr);
351
if ((recv_size = recv_from_socket(data->sock, buffer, recv_size)) < 0)
217
if (recv_from_socket(data->sock, data->comm.buf,
218
sizeof(struct tcsd_packet_hdr)) < 0)
353
buffer += sizeof(struct tcsd_packet_hdr); /* increment the buffer pointer */
221
recd_so_far = sizeof(struct tcsd_packet_hdr);
355
223
/* check the packet size */
356
recv_size = Decode_UINT32(data->comm.buf);
357
if (recv_size < (int)sizeof(struct tcsd_packet_hdr)) {
224
total_recv_size = Decode_UINT32(data->comm.buf);
225
if (total_recv_size < (int)sizeof(struct tcsd_packet_hdr)) {
358
226
LogError("Packet to receive from socket %d is too small (%d bytes)",
359
data->sock, recv_size);
227
data->sock, total_recv_size);
363
if (recv_size > (int) data->comm.buf_size ) {
231
LogDebug("total_recv_size %d, buf_size %u, recd_so_far %d", total_recv_size,
232
data->comm.buf_size, recd_so_far);
234
empty_space = data->comm.buf_size - recd_so_far;
236
/* instead of blindly allocating recv_size bytes off the bat, stage the realloc
237
* and wait for the data to come in over the socket. This protects against
238
* trivially asking tcsd to alloc 2GB */
239
while (total_recv_size > (int) data->comm.buf_size) {
364
240
BYTE *new_buffer;
366
LogDebug("Increasing communication buffer to %d bytes.", recv_size);
367
new_buffer = realloc(data->comm.buf, recv_size);
243
if ((int)data->comm.buf_size + TCSD_INCR_TXBUF_SIZE < total_recv_size) {
244
new_bufsize = data->comm.buf_size + TCSD_INCR_TXBUF_SIZE;
245
recv_chunk_size = empty_space + TCSD_INCR_TXBUF_SIZE;
247
new_bufsize = total_recv_size;
248
recv_chunk_size = total_recv_size - recd_so_far;
251
LogDebug("Increasing communication buffer to %d bytes.", new_bufsize);
252
new_buffer = realloc(data->comm.buf, new_bufsize);
368
253
if (new_buffer == NULL) {
369
LogError("realloc of %d bytes failed.", recv_size);
254
LogError("realloc of %d bytes failed.", new_bufsize);
255
data->comm.buf = NULL;
372
buffer = new_buffer + sizeof(struct tcsd_packet_hdr);
373
data->comm.buf_size = recv_size;
259
data->comm.buf_size = new_bufsize;
374
260
data->comm.buf = new_buffer;
377
/* get the rest of the packet */
378
recv_size -= sizeof(struct tcsd_packet_hdr); /* already received the header */
379
if ((recv_size = recv_from_socket(data->sock, buffer, recv_size)) < 0)
261
buffer = data->comm.buf + recd_so_far;
263
LogDebug("recv_chunk_size %d recd_so_far %d", recv_chunk_size, recd_so_far);
264
if (recv_from_socket(data->sock, buffer, recv_chunk_size) < 0) {
265
result = TCSERR(TSS_E_INTERNAL_ERROR);
269
recd_so_far += recv_chunk_size;
273
if (recd_so_far < total_recv_size) {
274
buffer = data->comm.buf + recd_so_far;
275
recv_chunk_size = total_recv_size - recd_so_far;
277
LogDebug("recv_chunk_size %d recd_so_far %d", recv_chunk_size, recd_so_far);
279
if (recv_from_socket(data->sock, buffer, recv_chunk_size) < 0) {
280
result = TCSERR(TSS_E_INTERNAL_ERROR);
381
284
LogDebug("Rx'd packet");
383
286
/* create a platform version of the tcsd header */