Browse code

ps.c debug code

git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@902 e7ae566f-a301-0410-adde-c780ea21d3b5

james authored on 2006/02/19 01:35:21
Showing 2 changed files
... ...
@@ -133,7 +133,7 @@
133 133
 #define D_ALIGN_DEBUG        LOGLEV(7, 70, M_DEBUG)  /* show verbose struct alignment info */
134 134
 #define D_PACKET_TRUNC_DEBUG LOGLEV(7, 70, M_DEBUG)  /* PACKET_TRUNCATION_CHECK verbose */
135 135
 #define D_PING               LOGLEV(7, 70, M_DEBUG)  /* PING send/receive messages */
136
-#define D_PS_PROXY_DEBUG     LOGLEV(7, 70, M_DEBUG)  /* port share proxy debug */
136
+#define D_PS_PROXY_DEBUG     LOGLEV(4, 70, M_DEBUG)  /* JYFIXME port share proxy debug */
137 137
 
138 138
 #define D_HANDSHAKE_VERBOSE  LOGLEV(8, 70, M_DEBUG)  /* show detailed description of each handshake */
139 139
 #define D_TLS_DEBUG_MED      LOGLEV(8, 70, M_DEBUG)  /* limited info from tls_session routines */
... ...
@@ -238,6 +238,19 @@ pc_list_len (struct proxy_connection *pc)
238 238
   return count;
239 239
 }
240 240
 
241
+static void
242
+proxy_entry_close_sd (struct proxy_connection *pc, struct event_set *es)
243
+{
244
+  if (pc->defined && socket_defined (pc->sd))
245
+    {
246
+      dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: delete sd=%d", pc->sd);
247
+      if (es)
248
+	event_del (es, pc->sd);
249
+      openvpn_close_socket (pc->sd);
250
+      pc->sd = SOCKET_UNDEFINED;
251
+    }
252
+}
253
+
241 254
 /*
242 255
  * Mark a proxy entry and its counterpart for close.
243 256
  */
... ...
@@ -247,18 +260,10 @@ proxy_entry_mark_for_close (struct proxy_connection *pc, struct event_set *es)
247 247
   if (pc->defined)
248 248
     {
249 249
       struct proxy_connection *cp = pc->counterpart;
250
-      dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: delete sd=%d", pc->sd);
251
-      if (socket_defined (pc->sd))
252
-	{
253
-	  if (es)
254
-	    event_del (es, pc->sd);
255
-	  openvpn_close_socket (pc->sd);
256
-	  pc->sd = SOCKET_UNDEFINED;
257
-	}
250
+      proxy_entry_close_sd (pc, es);
258 251
       free_buf (&pc->buf);
259 252
       pc->buffer_initial = false;
260 253
       pc->rwflags = 0;
261
-      pc->counterpart = NULL;
262 254
       pc->defined = false;
263 255
       if (cp && cp->defined && cp->counterpart == pc)
264 256
 	proxy_entry_mark_for_close (cp, es);
... ...
@@ -327,7 +332,7 @@ sock_addr_set (struct openvpn_sockaddr *osaddr,
327 327
 static inline void
328 328
 proxy_connection_io_requeue (struct proxy_connection *pc, const int rwflags_new, struct event_set *es)
329 329
 {
330
-  if (pc->rwflags != rwflags_new)
330
+  if (socket_defined (pc->sd) && pc->rwflags != rwflags_new)
331 331
     {
332 332
       event_ctl (es, pc->sd, rwflags_new, (void*)pc);
333 333
       pc->rwflags = rwflags_new;
... ...
@@ -489,67 +494,120 @@ control_message_from_parent (const socket_descriptor_t sd_control,
489 489
   return ret;
490 490
 }
491 491
 
492
-/* proxy_connection_io_xfer return values */
492
+/*
493
+ * Return values for proxy_connection_io functions
494
+ */
495
+
496
+#define IOSTAT_UNDEF            0
497
+#define IOSTAT_EAGAIN_ON_READ   1 /* recv returned EAGAIN */
498
+#define IOSTAT_EAGAIN_ON_WRITE  2 /* send returned EAGAIN */
499
+#define IOSTAT_READ_ERROR       3 /* the other end of our read socket (pc) was closed */
500
+#define IOSTAT_WRITE_ERROR      4 /* the other end of our write socket (pc->counterpart) was closed */
501
+#define IOSTAT_BOTH_CLOSED      5 /* both sockets are closed, preventing action */
502
+#define IOSTAT_HALF_CLOSED_1    6 /* one socket is closed, preventing action */
503
+#define IOSTAT_HALF_CLOSED_2    7 /* one socket is closed, preventing action */
504
+#define IOSTAT_GOOD             8 /* nothing to report */
505
+#define IOSTAT_ASYMFLUSH        9 /* pc socket is closed, flushed send data to pc->counterpart socket */
506
+
507
+static int
508
+proxy_connection_io_recv (struct proxy_connection *pc)
509
+{
510
+  /* recv data from socket */
511
+  ssize_t status = recv (pc->sd, BPTR(&pc->buf), BCAP(&pc->buf), MSG_NOSIGNAL);
512
+  if (status == -1)
513
+    {
514
+      return (errno == EAGAIN) ? IOSTAT_EAGAIN_ON_READ : IOSTAT_READ_ERROR;
515
+    }
516
+  else
517
+    {
518
+      if (!status)
519
+	return IOSTAT_READ_ERROR;
520
+      pc->buf.len = status;
521
+    }
522
+  return IOSTAT_GOOD;
523
+}
524
+
525
+static int
526
+proxy_connection_io_send (struct proxy_connection *pc)
527
+{
528
+  if ((get_random() % 4096) == 0) // JYFIXME
529
+    {
530
+      /* send data to counterpart socket */
531
+      ssize_t status = send (pc->counterpart->sd, BPTR(&pc->buf), BLEN(&pc->buf), MSG_NOSIGNAL);
532
+      if (status == -1)
533
+	{
534
+	  const int e = errno;
535
+	  return (e == EAGAIN) ? IOSTAT_EAGAIN_ON_WRITE : IOSTAT_WRITE_ERROR;
536
+	}
537
+      else
538
+	{
539
+	  if (status != pc->buf.len)
540
+	    return IOSTAT_WRITE_ERROR;
541
+	  pc->buf.len = 0;
542
+	}
493 543
 
494
-#define IOSTAT_EAGAIN_ON_READ   0
495
-#define IOSTAT_EAGAIN_ON_WRITE  1
496
-#define IOSTAT_ERROR            2
544
+      /* realloc send buffer after initial send */
545
+      if (pc->buffer_initial)
546
+	{
547
+	  free_buf (&pc->buf);
548
+	  pc->buf = alloc_buf (PROXY_CONNECTION_BUFFER_SIZE);
549
+	  pc->buffer_initial = false;
550
+	}
551
+      return IOSTAT_GOOD;
552
+    }
553
+  return IOSTAT_EAGAIN_ON_WRITE;
554
+}
497 555
 
498 556
 /*
499 557
  * Forward data from pc to pc->counterpart.
500
- * Return values:
501
- *
502
- * IOSTAT_EAGAIN_ON_READ -- recv returned EAGAIN
503
- * IOSTAT_EAGAIN_ON_WRITE -- send return EAGAIN
504
- * IOSTAT_ERROR -- the other end of one of our sockets was closed
505 558
  */
559
+
506 560
 static int
507 561
 proxy_connection_io_xfer (struct proxy_connection *pc)
508 562
 {
509
-  while (true)
563
+  const bool sd_defined = (pc->defined && socket_defined (pc->sd));
564
+  const bool sd_counterpart_defined = (pc->counterpart->defined && socket_defined (pc->counterpart->sd));
565
+
566
+  if (sd_defined && sd_counterpart_defined)
510 567
     {
511
-      if (!BLEN (&pc->buf))
568
+      while (true)
512 569
 	{
513
-	  /* recv data from socket */
514
-	  ssize_t status = recv (pc->sd, BPTR(&pc->buf), BCAP(&pc->buf), MSG_NOSIGNAL);
515
-	  if (status == -1)
570
+	  if (!BLEN (&pc->buf))
516 571
 	    {
517
-	      return (errno == EAGAIN) ? IOSTAT_EAGAIN_ON_READ : IOSTAT_ERROR;
572
+	      const int status = proxy_connection_io_recv (pc);
573
+	      if (status != IOSTAT_GOOD)
574
+		return status;
518 575
 	    }
519
-	  else
576
+
577
+	  if (BLEN (&pc->buf))
520 578
 	    {
521
-	      if (!status)
522
-		return IOSTAT_ERROR;
523
-	      pc->buf.len = status;
579
+	      const int status = proxy_connection_io_send (pc);
580
+	      if (status != IOSTAT_GOOD)
581
+		return status;
524 582
 	    }
525 583
 	}
526
-
584
+    }
585
+  else if (!sd_defined && sd_counterpart_defined)
586
+    {
527 587
       if (BLEN (&pc->buf))
528 588
 	{
529
-	  /* send data to counterpart socket */
530
-	  ssize_t status = send (pc->counterpart->sd, BPTR(&pc->buf), BLEN(&pc->buf), MSG_NOSIGNAL);
531
-	  if (status == -1)
532
-	    {
533
-	      const int e = errno;
534
-	      return (e == EAGAIN) ? IOSTAT_EAGAIN_ON_WRITE : IOSTAT_ERROR;
535
-	    }
536
-	  else
537
-	    {
538
-	      if (status != pc->buf.len)
539
-		return IOSTAT_ERROR;
540
-	      pc->buf.len = 0;
541
-	    }
542
-
543
-	  /* successful send */
544
-	  if (pc->buffer_initial)
545
-	    {
546
-	      free_buf (&pc->buf);
547
-	      pc->buf = alloc_buf (PROXY_CONNECTION_BUFFER_SIZE);
548
-	      pc->buffer_initial = false;
549
-	    }
589
+	  /*
590
+	   * One side of the connection has been closed, but the other side is open
591
+	   * and still has pending output which must be sent before closure.
592
+	   */
593
+	  const int status = proxy_connection_io_send (pc);
594
+	  dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: asymmetric flush on sd=%d status=%d",
595
+		pc->counterpart->sd, status);
596
+	  return (status == IOSTAT_EAGAIN_ON_WRITE) ? IOSTAT_EAGAIN_ON_WRITE : IOSTAT_ASYMFLUSH;
550 597
 	}
598
+      else
599
+	return IOSTAT_HALF_CLOSED_1;
600
+    }
601
+  else if (sd_defined && !sd_counterpart_defined)
602
+    {
603
+      return IOSTAT_HALF_CLOSED_2;
551 604
     }
552
-  return IOSTAT_ERROR;
605
+  return IOSTAT_BOTH_CLOSED;
553 606
 }
554 607
 
555 608
 /*
... ...
@@ -560,16 +618,45 @@ proxy_connection_io_status (const int status, int *rwflags_pc, int *rwflags_cp)
560 560
 {
561 561
   switch (status)
562 562
     {
563
-	case IOSTAT_EAGAIN_ON_READ:
564
-	  *rwflags_pc |= EVENT_READ;
565
-	  *rwflags_cp &= ~EVENT_WRITE;
566
-	  return true;
567
-	case IOSTAT_EAGAIN_ON_WRITE:
568
-	  *rwflags_pc &= ~EVENT_READ;
569
-	  *rwflags_cp |= EVENT_WRITE;
570
-	  return true;
571
-	default:
572
-	  return false;
563
+    case IOSTAT_EAGAIN_ON_READ:
564
+      *rwflags_pc |= EVENT_READ;
565
+      *rwflags_cp &= ~EVENT_WRITE;
566
+      return true;
567
+    case IOSTAT_EAGAIN_ON_WRITE:
568
+      *rwflags_pc &= ~EVENT_READ;
569
+      *rwflags_cp |= EVENT_WRITE;
570
+      return true;
571
+    default:
572
+      return false;
573
+    }
574
+}
575
+
576
+static void
577
+proxy_connection_close (struct proxy_connection *pc, struct event_set *es)
578
+{
579
+  if (BLEN (&pc->buf) && pc->counterpart && socket_defined (pc->counterpart->sd))
580
+    proxy_entry_close_sd (pc, es);          /* close one side of the connection (pc) */
581
+  else
582
+    proxy_entry_mark_for_close (pc, es);    /* close both sides of the connection */
583
+}
584
+
585
+static void
586
+proxy_connection_exception (struct proxy_connection *pc, const int status, struct event_set *es)
587
+{
588
+  dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: proxy_connection_exception, status=%d", status);
589
+  switch (status)
590
+    {
591
+    case IOSTAT_READ_ERROR:
592
+      proxy_connection_close (pc, es);
593
+      break;
594
+    case IOSTAT_WRITE_ERROR:
595
+      proxy_connection_close (pc->counterpart, es);
596
+      break;
597
+    case IOSTAT_ASYMFLUSH:
598
+      proxy_entry_mark_for_close (pc, es); /* close both sides of the connection */
599
+      break;
600
+    default:
601
+      break;
573 602
     }
574 603
 }
575 604
 
... ...
@@ -577,36 +664,29 @@ proxy_connection_io_status (const int status, int *rwflags_pc, int *rwflags_cp)
577 577
  * Dispatch function for forwarding data between the two socket fds involved
578 578
  * in the proxied connection.
579 579
  */
580
-static bool
580
+static void
581 581
 proxy_connection_io_dispatch (struct proxy_connection *pc,
582 582
 			      const int rwflags,
583 583
 			      struct event_set *es)
584 584
 {
585 585
   struct proxy_connection *cp = pc->counterpart;
586
-  int status;
587 586
   int rwflags_pc = pc->rwflags;
588 587
   int rwflags_cp = cp->rwflags;
589 588
 
590 589
   if (rwflags & EVENT_READ)
591 590
     {
592
-      status = proxy_connection_io_xfer (pc);
591
+      const int status = proxy_connection_io_xfer (pc);
593 592
       if (!proxy_connection_io_status (status, &rwflags_pc, &rwflags_cp))
594
-	goto bad;
593
+	proxy_connection_exception (pc, status, es);
595 594
     }
596 595
   if (rwflags & EVENT_WRITE)
597 596
     {
598
-      status = proxy_connection_io_xfer (cp);
597
+      const int status = proxy_connection_io_xfer (cp);
599 598
       if (!proxy_connection_io_status (status, &rwflags_cp, &rwflags_pc))
600
-	goto bad;
599
+	proxy_connection_exception (pc, status, es);
601 600
     }
602 601
   proxy_connection_io_requeue (pc, rwflags_pc, es);
603 602
   proxy_connection_io_requeue (cp, rwflags_cp, es);
604
-
605
-  return true;
606
-
607
- bad:
608
-  proxy_entry_mark_for_close (pc, es);
609
-  return false;
610 603
 }
611 604
 
612 605
 /*