~ubuntu-branches/ubuntu/saucy/trousers/saucy

« back to all changes in this revision

Viewing changes to src/tcsd/tcsd_threads.c

  • Committer: Logan Rosen
  • Date: 2012-11-30 16:31:54 UTC
  • mfrom: (0.1.25 sid)
  • Revision ID: logatronico@gmail.com-20121130163154-jllqpry4lo24ol6p
* Merge from Debian unstable. Remaining changes:
  - debian/trousers.postinst: Reload udev rules to reload new users and
    groups.
* Dropped Ubuntu change in debian/trousers.prerm to make remove work,
  as Debian made a different one with the same goal that works as well.
* Imported Upstream version 0.3.10
* Update symbols file
* Force build of tools
* Fix regression introduced in previous patch, preventing removal
  (Closes: #680375)

Show diffs side-by-side

added added

removed removed

Lines of Context:
195
195
                THREAD_EXIT(NULL);
196
196
        }
197
197
}
198
 
#if 0
199
 
void *
200
 
tcsd_thread_run(void *v)
201
 
{
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;
205
 
        TSS_RESULT result;
206
 
        int sizeToSend, sent_total, sent;
207
 
        UINT64 offset;
208
 
#ifndef TCSD_SINGLE_THREAD_DEBUG
209
 
        int rc;
210
 
 
211
 
        thread_signal_init();
212
 
#endif
213
 
 
214
 
        if ((data->buf_size = recv(data->sock, buffer, TCSD_TXBUF_SIZE, 0)) < 0) {
215
 
                LogError("Failed Receive: %s", strerror(errno));
216
 
                goto done;
217
 
        }
218
 
        LogDebug("Rx'd packet");
219
 
 
220
 
        data->buf = buffer;
221
 
 
222
 
        while (1) {
223
 
                sent_total = 0;
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);
227
 
                        goto done;
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);
231
 
                        goto done;
232
 
                }
233
 
 
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().
239
 
                         */
240
 
                        offset = 0;
241
 
                        /* load result */
242
 
                        LoadBlob_UINT32(&offset, result, buffer);
243
 
                        /* load packet size */
244
 
                        LoadBlob_UINT32(&offset, sizeof(struct tcsd_packet_hdr), buffer);
245
 
                        /* load num parms */
246
 
                        LoadBlob_UINT16(&offset, 0, buffer);
247
 
 
248
 
                        sizeToSend = sizeof(struct tcsd_packet_hdr);
249
 
                        LogDebug("Sending 0x%X bytes back", sizeToSend);
250
 
 
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.",
256
 
                                                        strerror(errno));
257
 
                                        goto done;
258
 
                                }
259
 
                                sent_total += sent;
260
 
                        }
261
 
                } else {
262
 
                        sizeToSend = Decode_UINT32((BYTE *)&(ret_buf->packet_size));
263
 
 
264
 
                        LogDebug("Sending 0x%X bytes back", sizeToSend);
265
 
 
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.",
271
 
                                                        strerror(errno));
272
 
                                        free(ret_buf);
273
 
                                        ret_buf = NULL;
274
 
                                        goto done;
275
 
                                }
276
 
                                sent_total += sent;
277
 
                        }
278
 
                        free(ret_buf);
279
 
                        ret_buf = NULL;
280
 
                }
281
 
 
282
 
                if (tm->shutdown) {
283
 
                        LogDebug("Thread %zd exiting via shutdown signal!", THREAD_ID);
284
 
                        break;
285
 
                }
286
 
 
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.",
290
 
                                 strerror(errno));
291
 
                        break;
292
 
                } else if (data->buf_size == 0) {
293
 
                        LogDebug("The TSP has closed the socket's connection. Thread exiting.");
294
 
                        break;
295
 
                }
296
 
        }
297
 
 
298
 
done:
299
 
        /* Closing connection to TSP */
300
 
        close(data->sock);
301
 
        data->sock = -1;
302
 
        data->buf = NULL;
303
 
        data->buf_size = -1;
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;
308
 
        }
309
 
 
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. */
315
 
        if (!tm->shutdown) {
316
 
                if ((rc = THREAD_DETACH(*(data->thread_id)))) {
317
 
                        LogError("Thread detach failed (errno %d)."
318
 
                                 " Resources may not be properly released.", rc);
319
 
                }
320
 
        }
321
 
        free(data->hostname);
322
 
        data->hostname = NULL;
323
 
        data->thread_id = THREAD_NULL;
324
 
        MUTEX_UNLOCK(tm->lock);
325
 
        THREAD_EXIT(NULL);
326
 
#else
327
 
        return NULL;
328
 
#endif
329
 
}
330
 
#else
 
198
 
331
199
void *
332
200
tcsd_thread_run(void *v)
333
201
{
334
202
        struct tcsd_thread_data *data = (struct tcsd_thread_data *)v;
335
203
        BYTE *buffer;
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;
338
206
        UINT64 offset;
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)
352
219
                        break;
353
 
                buffer += sizeof(struct tcsd_packet_hdr);       /* increment the buffer pointer */
 
220
 
 
221
                recd_so_far = sizeof(struct tcsd_packet_hdr);
354
222
 
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);
360
228
                        break;
361
229
                }
362
230
 
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);
 
233
 
 
234
                empty_space = data->comm.buf_size - recd_so_far;
 
235
 
 
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;
365
 
 
366
 
                        LogDebug("Increasing communication buffer to %d bytes.", recv_size);
367
 
                        new_buffer = realloc(data->comm.buf, recv_size);
 
241
                        int new_bufsize;
 
242
 
 
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;
 
246
                        } else {
 
247
                                new_bufsize = total_recv_size;
 
248
                                recv_chunk_size = total_recv_size - recd_so_far;
 
249
                        }
 
250
 
 
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);
370
 
                                break;
 
254
                                LogError("realloc of %d bytes failed.", new_bufsize);
 
255
                                data->comm.buf = NULL;
 
256
                                goto no_mem_error;
371
257
                        }
372
 
                        buffer = new_buffer + sizeof(struct tcsd_packet_hdr);
373
 
                        data->comm.buf_size = recv_size;
 
258
 
 
259
                        data->comm.buf_size = new_bufsize;
374
260
                        data->comm.buf = new_buffer;
375
 
                }
376
 
 
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)
380
 
                        break;
 
261
                        buffer = data->comm.buf + recd_so_far;
 
262
 
 
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);
 
266
                                goto error;
 
267
                        }
 
268
 
 
269
                        recd_so_far += recv_chunk_size;
 
270
                        empty_space = 0;
 
271
                }
 
272
 
 
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;
 
276
 
 
277
                        LogDebug("recv_chunk_size %d recd_so_far %d", recv_chunk_size, recd_so_far);
 
278
 
 
279
                        if (recv_from_socket(data->sock, buffer, recv_chunk_size) < 0) {
 
280
                                result = TCSERR(TSS_E_INTERNAL_ERROR);
 
281
                                goto error;
 
282
                        }
 
283
                }
381
284
                LogDebug("Rx'd packet");
382
285
 
383
286
                /* create a platform version of the tcsd header */
390
293
                UnloadBlob_UINT32(&offset, &data->comm.hdr.parm_size, data->comm.buf);
391
294
                UnloadBlob_UINT32(&offset, &data->comm.hdr.parm_offset, data->comm.buf);
392
295
 
393
 
                if ((result = getTCSDPacket(data)) != TSS_SUCCESS) {
 
296
                result = getTCSDPacket(data);
 
297
error:
 
298
                if (result) {
394
299
                        /* something internal to the TCSD went wrong in preparing the packet
395
300
                         * to return to the TSP.  Use our already allocated buffer to return a
396
301
                         * TSS_E_INTERNAL_ERROR return code to the TSP. In the non-error path,
416
321
                        break;
417
322
                }
418
323
        }
419
 
 
 
324
no_mem_error:
420
325
        LogDebug("Thread exiting.");
421
326
 
422
327
        /* Closing connection to TSP */
453
358
#endif
454
359
        return NULL;
455
360
}
456
 
 
457
 
#endif