]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
DEV: poll: make the connect() step an action as well
authorWilly Tarreau <w@1wt.eu>
Thu, 17 Nov 2022 06:44:27 +0000 (07:44 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 17 Nov 2022 09:56:35 +0000 (10:56 +0100)
Now the connect() step becomes an action. It's still implicit before
any -c/-s but it allows the listener to close() before connect()
happens, showing the polling status for this condition:

  $ dev/poll/poll -v -l clo -c pol
  #### BEGIN ####
  cmd #1 stp #1: do_clo(3): ret=0
  cmd #2 stp #0: do_con(4): ret=-1 (Connection refused)
  cmd #2 stp #1: do_pol(4): ret=1 ev=0x14 (OUT HUP)
  #### END ####

which differs from a case where the server closes the just accepted
connection:

  $ dev/poll/poll -v -s clo -c pol
  #### BEGIN ####
  cmd #1 stp #0: do_con(4): ret=0
  cmd #1 stp #0: do_acc(3): ret=5
  cmd #1 stp #1: do_clo(5): ret=0
  cmd #2 stp #1: do_pol(4): ret=1 ev=0x2005 (IN OUT RDHUP)
  #### END ####

It's interesting to see OUT+HUP since HUP indicates that both directions
were closed, hence nothing may be written now, thus OUT just wants the
write handler to be notified.

dev/poll/poll.c

index 55f922aaaf1b2a1865c53fcc6c42e99f7580b0b2..91db039d87170549f4cbe923758a38ff337afc68 100644 (file)
@@ -32,6 +32,7 @@ int one  = 1;
 int lfd = -1;
 int cfd = -1;
 int sfd = -1;
+int connected = 0;
 struct sockaddr_in saddr, caddr;
 socklen_t salen, calen;
 
@@ -46,6 +47,7 @@ void usage(const char *arg0)
               "    -l <actions>  perform <action> on listening socket\n"
               "\n"
               "actions for -c/-s/-l (multiple may be delimited by commas) :\n"
+              "    con           connect to listener, implicit before first -c/-s\n"
               "    acc           accept on listener, implicit before first -s\n"
               "    snd           send a few bytes of data\n"
               "    mor           send a few bytes of data with MSG_MORE\n"
@@ -90,6 +92,16 @@ void do_acc(int fd)
                printf("cmd #%d stp #%d: %s(%d): ret=%d%s\n", cmd, cmdstep, __FUNCTION__, fd, ret, get_errno(ret));
 }
 
+void do_con(int fd)
+{
+       int ret;
+
+        ret = connect(cfd, (const struct sockaddr*)&saddr, salen);
+       if (verbose)
+               printf("cmd #%d stp #%d: %s(%d): ret=%d%s\n", cmd, cmdstep, __FUNCTION__, fd, ret, get_errno(ret));
+       connected = 1;
+}
+
 void do_snd(int fd)
 {
        int ret;
@@ -251,13 +263,6 @@ int main(int argc, char **argv)
        if (cfd < 0)
                die("socket(c)");
 
-        if (connect(cfd, (const struct sockaddr*)&saddr, salen) == -1)
-               die("connect()");
-
-       /* connection is pending in accept queue, accept() will either be
-        * explicit with "-l acc" below, or implicit on "-s <cmd>"
-        */
-
        arg0 = argv[0];
        if (argc < 2) {
                usage(arg0);
@@ -284,10 +289,18 @@ int main(int argc, char **argv)
                        break;
                case 'c' :
                        cmd++; cmdstep = 0;
+                       if (!connected) {
+                               do_con(cfd);
+                               /* connection is pending in accept queue, accept() will either be
+                                * explicit with "-l acc" below, or implicit on "-s <cmd>"
+                                */
+                       }
                        fd = cfd;
                        break;
                case 's' :
                        cmd++; cmdstep = 0;
+                       if (!connected)
+                               do_con(cfd);
                        if (sfd < 0)
                                do_acc(lfd);
                        if (sfd < 0)
@@ -315,6 +328,9 @@ int main(int argc, char **argv)
                                if (strcmp(word, "acc") == 0) {
                                        do_acc(fd);
                                }
+                               else if (strcmp(word, "con") == 0) {
+                                       do_con(fd);
+                               }
                                else if (strcmp(word, "snd") == 0) {
                                        do_snd(fd);
                                }