aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Dash Shendy 2011-07-08 22:55:17 +0200
committerGravatar Dash Shendy 2011-07-08 22:55:17 +0200
commitb4a875b12ad2ef07f38ae23b3d3e853b5a59bf89 (patch)
treec6b9c824f3b1c8d953d5bbda80008503799e4308 /src
parentb59327cde81cddced2a35742bd203c242669d6dc (diff)
EOC Bucket Infinite Loop Bugfix
Signed-off-by: Dash Shendy <neuromancer@dash.za.net>
Diffstat (limited to 'src')
-rw-r--r--src/gnutls_io.c85
1 files changed, 35 insertions, 50 deletions
diff --git a/src/gnutls_io.c b/src/gnutls_io.c
index 37b73e7..4a550c3 100644
--- a/src/gnutls_io.c
+++ b/src/gnutls_io.c
@@ -541,7 +541,6 @@ apr_status_t mgs_filter_input(ap_filter_t * f,
541apr_status_t mgs_filter_output(ap_filter_t * f, apr_bucket_brigade * bb) 541apr_status_t mgs_filter_output(ap_filter_t * f, apr_bucket_brigade * bb)
542{ 542{
543 apr_size_t ret; 543 apr_size_t ret;
544 apr_bucket *e;
545 mgs_handle_t *ctxt = (mgs_handle_t *) f->ctx; 544 mgs_handle_t *ctxt = (mgs_handle_t *) f->ctx;
546 apr_status_t status = APR_SUCCESS; 545 apr_status_t status = APR_SUCCESS;
547 apr_read_type_e rblock = APR_NONBLOCK_READ; 546 apr_read_type_e rblock = APR_NONBLOCK_READ;
@@ -562,48 +561,32 @@ apr_status_t mgs_filter_output(ap_filter_t * f, apr_bucket_brigade * bb)
562 while (!APR_BRIGADE_EMPTY(bb)) { 561 while (!APR_BRIGADE_EMPTY(bb)) {
563 apr_bucket *bucket = APR_BRIGADE_FIRST(bb); 562 apr_bucket *bucket = APR_BRIGADE_FIRST(bb);
564 563
565 if (AP_BUCKET_IS_EOC(bucket)) { 564 if (AP_BUCKET_IS_EOS(bucket)) {
566 if (ctxt->session != NULL) { 565 return ap_pass_brigade(f->next, bb);
567 do { 566 } else if (APR_BUCKET_IS_FLUSH(bucket)) {
568 ret = 567 /* Try Flush */
569 gnutls_bye(ctxt->session, 568 if( write_flush(ctxt) < 0) {
570 GNUTLS_SHUT_WR); 569 /* Flush Error */
571 } while (ret == GNUTLS_E_INTERRUPTED 570 return ctxt->output_rc;
572 || ret == GNUTLS_E_AGAIN); 571 }
573 } 572 /* cleanup! */
574 573 apr_bucket_delete(bucket);
575 apr_bucket_copy(bucket, &e); 574 } else if (AP_BUCKET_IS_EOC(bucket)) {
576 APR_BRIGADE_INSERT_TAIL(ctxt->output_bb, e); 575 /* End Of Connection */
577 576 if (ctxt->session != NULL) {
578 if ((status = 577 /* Try A Clean Shutdown */
579 ap_pass_brigade(f->next, 578 do {
580 ctxt->output_bb)) != 579 ret = gnutls_bye( ctxt->session,
581 APR_SUCCESS) { 580 GNUTLS_SHUT_WR);
582 apr_brigade_cleanup(ctxt->output_bb); 581 } while(ret == GNUTLS_E_INTERRUPTED ||
583 return status; 582 ret == GNUTLS_E_AGAIN);
584 } 583 /* De-Initialize Session */
585 584 gnutls_deinit(ctxt->session);
586 apr_brigade_cleanup(ctxt->output_bb); 585 ctxt->session = NULL;
587 if (ctxt->session) { 586 }
588 gnutls_deinit(ctxt->session); 587 /* Pass next brigade! */
589 ctxt->session = NULL; 588 return ap_pass_brigade(f->next, bb);
590 } 589 } else {
591 continue;
592 } else if (APR_BUCKET_IS_FLUSH(bucket)
593 || APR_BUCKET_IS_EOS(bucket)) {
594
595 apr_bucket_copy(bucket, &e);
596 APR_BRIGADE_INSERT_TAIL(ctxt->output_bb, e);
597 if ((status =
598 ap_pass_brigade(f->next,
599 bb)) != APR_SUCCESS) {
600 apr_brigade_cleanup(ctxt->output_bb);
601 return status;
602 }
603
604 apr_brigade_cleanup(ctxt->output_bb);
605 continue;
606 } else {
607 /* filter output */ 590 /* filter output */
608 const char *data; 591 const char *data;
609 apr_size_t len; 592 apr_size_t len;
@@ -612,15 +595,20 @@ apr_status_t mgs_filter_output(ap_filter_t * f, apr_bucket_brigade * bb)
612 apr_bucket_read(bucket, &data, &len, rblock); 595 apr_bucket_read(bucket, &data, &len, rblock);
613 596
614 if (APR_STATUS_IS_EAGAIN(status)) { 597 if (APR_STATUS_IS_EAGAIN(status)) {
615 rblock = APR_BLOCK_READ; 598 /* No data available so Flush! */
616 continue; /* and try again with a blocking read. */ 599 if (write_flush(ctxt) < 0) {
600 return ctxt->output_rc;
601 }
602 /* Try again with a blocking read. */
603 rblock = APR_BLOCK_READ;
604 continue;
617 } 605 }
618 606
619 rblock = APR_NONBLOCK_READ; 607 rblock = APR_NONBLOCK_READ;
620 608
621 if (!APR_STATUS_IS_EOF(status) 609 if (!APR_STATUS_IS_EOF(status)
622 && (status != APR_SUCCESS)) { 610 && (status != APR_SUCCESS)) {
623 break; 611 return status;
624 } 612 }
625 613
626 if (len > 0) { 614 if (len > 0) {
@@ -651,6 +639,7 @@ apr_status_t mgs_filter_output(ap_filter_t * f, apr_bucket_brigade * bb)
651 if (ctxt->output_rc == APR_SUCCESS) { 639 if (ctxt->output_rc == APR_SUCCESS) {
652 ctxt->output_rc = 640 ctxt->output_rc =
653 APR_EGENERAL; 641 APR_EGENERAL;
642 return ctxt->output_rc;
654 } 643 }
655 } else if (ret != len) { 644 } else if (ret != len) {
656 /* Not able to send the entire bucket, 645 /* Not able to send the entire bucket,
@@ -660,10 +649,6 @@ apr_status_t mgs_filter_output(ap_filter_t * f, apr_bucket_brigade * bb)
660 } 649 }
661 650
662 apr_bucket_delete(bucket); 651 apr_bucket_delete(bucket);
663
664 if (ctxt->output_rc != APR_SUCCESS) {
665 break;
666 }
667 } 652 }
668 } 653 }
669 654