aboutsummaryrefslogtreecommitdiffstats
path: root/src/gnutls.c
diff options
context:
space:
mode:
authorLars Ingebrigtsen2016-02-16 15:56:56 +1100
committerLars Ingebrigtsen2016-02-16 15:56:56 +1100
commitac6e085cf6b26257cfe181f17828432d414cb3a6 (patch)
tree9d382588ce869a2b816373e278b2805ffbb90f59 /src/gnutls.c
parentc43bb7f136ab9e9439a4b5c045040a12cbe8bda0 (diff)
downloademacs-ac6e085cf6b26257cfe181f17828432d414cb3a6.tar.gz
emacs-ac6e085cf6b26257cfe181f17828432d414cb3a6.zip
Implement asynch TLS negotiation
* src/gnutls.c (gnutls_try_handshake): Factor out into its own function. (emacs_gnutls_handshake): Use it. (emacs_gnutls_read): Just return instead of retrying the handshake. * src/process.c (finish_after_tls_connection): Factor out into its own function. (connect_network_socket): Use it. (wait_reading_process_output): Retry TLS handshakes. (wait_reading_process_output): Defer sentinel until TLS completes.
Diffstat (limited to 'src/gnutls.c')
-rw-r--r--src/gnutls.c71
1 files changed, 34 insertions, 37 deletions
diff --git a/src/gnutls.c b/src/gnutls.c
index 948a0c56f14..6573c87cf78 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -397,11 +397,42 @@ gnutls_log_function2i (int level, const char *string, int extra)
397 message ("gnutls.c: [%d] %s %d", level, string, extra); 397 message ("gnutls.c: [%d] %s %d", level, string, extra);
398} 398}
399 399
400int
401gnutls_try_handshake (struct Lisp_Process *proc)
402{
403 gnutls_session_t state = proc->gnutls_state;
404 int ret;
405
406 do
407 {
408 ret = gnutls_handshake (state);
409 emacs_gnutls_handle_error (state, ret);
410 QUIT;
411 }
412 while (ret < 0 && gnutls_error_is_fatal (ret) == 0 &&
413 ! proc->is_non_blocking_client);
414
415 proc->gnutls_initstage = GNUTLS_STAGE_HANDSHAKE_TRIED;
416
417 if (proc->is_non_blocking_client)
418 proc->gnutls_p = 1;
419
420 if (ret == GNUTLS_E_SUCCESS)
421 {
422 /* Here we're finally done. */
423 proc->gnutls_initstage = GNUTLS_STAGE_READY;
424 }
425 else
426 {
427 //check_memory_full (gnutls_alert_send_appropriate (state, ret));
428 }
429 return ret;
430}
431
400static int 432static int
401emacs_gnutls_handshake (struct Lisp_Process *proc) 433emacs_gnutls_handshake (struct Lisp_Process *proc)
402{ 434{
403 gnutls_session_t state = proc->gnutls_state; 435 gnutls_session_t state = proc->gnutls_state;
404 int ret;
405 436
406 if (proc->gnutls_initstage < GNUTLS_STAGE_HANDSHAKE_CANDO) 437 if (proc->gnutls_initstage < GNUTLS_STAGE_HANDSHAKE_CANDO)
407 return -1; 438 return -1;
@@ -443,26 +474,7 @@ emacs_gnutls_handshake (struct Lisp_Process *proc)
443 proc->gnutls_initstage = GNUTLS_STAGE_TRANSPORT_POINTERS_SET; 474 proc->gnutls_initstage = GNUTLS_STAGE_TRANSPORT_POINTERS_SET;
444 } 475 }
445 476
446 do 477 return gnutls_try_handshake (proc);
447 {
448 ret = gnutls_handshake (state);
449 emacs_gnutls_handle_error (state, ret);
450 QUIT;
451 }
452 while (ret < 0 && gnutls_error_is_fatal (ret) == 0);
453
454 proc->gnutls_initstage = GNUTLS_STAGE_HANDSHAKE_TRIED;
455
456 if (ret == GNUTLS_E_SUCCESS)
457 {
458 /* Here we're finally done. */
459 proc->gnutls_initstage = GNUTLS_STAGE_READY;
460 }
461 else
462 {
463 check_memory_full (gnutls_alert_send_appropriate (state, ret));
464 }
465 return ret;
466} 478}
467 479
468ptrdiff_t 480ptrdiff_t
@@ -531,23 +543,8 @@ emacs_gnutls_read (struct Lisp_Process *proc, char *buf, ptrdiff_t nbyte)
531 int log_level = proc->gnutls_log_level; 543 int log_level = proc->gnutls_log_level;
532 544
533 if (proc->gnutls_initstage != GNUTLS_STAGE_READY) 545 if (proc->gnutls_initstage != GNUTLS_STAGE_READY)
534 { 546 return -1;
535 /* If the handshake count is under the limit, try the handshake
536 again and increment the handshake count. This count is kept
537 per process (connection), not globally. */
538 if (proc->gnutls_handshakes_tried < GNUTLS_EMACS_HANDSHAKES_LIMIT)
539 {
540 proc->gnutls_handshakes_tried++;
541 emacs_gnutls_handshake (proc);
542 GNUTLS_LOG2i (5, log_level, "Retried handshake",
543 proc->gnutls_handshakes_tried);
544 return -1;
545 }
546 547
547 GNUTLS_LOG (2, log_level, "Giving up on handshake; resetting retries");
548 proc->gnutls_handshakes_tried = 0;
549 return 0;
550 }
551 rtnval = gnutls_record_recv (state, buf, nbyte); 548 rtnval = gnutls_record_recv (state, buf, nbyte);
552 if (rtnval >= 0) 549 if (rtnval >= 0)
553 return rtnval; 550 return rtnval;