]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: peers: Extract some code to be reused.
authorFrédéric Lécaille <flecaille@haproxy.com>
Mon, 21 Jan 2019 12:38:06 +0000 (13:38 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 29 Jan 2019 09:29:54 +0000 (10:29 +0100)
May be backported as far as 1.5.

src/peers.c

index d4d3859e3d65e25935a97b7a59247103cd78a7fb..3a6394624cdfcca7b1a1aebba5c38e4e0c6fe28a 100644 (file)
@@ -561,6 +561,36 @@ static int peer_get_version(const char *str,
        return 0;
 }
 
+/*
+ * Parse a line terminated by an optional '\r' character, followed by a mandatory
+ * '\n' character.
+ * Returns 1 if succeeded or 0 if a '\n' character could not be found, and -1 if
+ * a line could not be read because the communication channel is closed.
+ */
+static inline int peer_getline(struct appctx  *appctx)
+{
+       int n;
+       struct stream_interface *si = appctx->owner;
+
+       n = co_getline(si_oc(si), trash.area, trash.size);
+       if (!n)
+               return 0;
+
+       if (n < 0 || trash.area[n - 1] != '\n') {
+               appctx->st0 = PEER_SESS_ST_END;
+               return -1;
+       }
+
+       if (n > 1 && (trash.area[n - 2] == '\r'))
+               trash.area[n - 2] = 0;
+       else
+               trash.area[n - 1] = 0;
+
+       co_skip(si_oc(si), n);
+
+       return n;
+}
+
 /*
  * IO Handler to handle message exchance with a peer
  */
@@ -592,24 +622,13 @@ switchstate:
                                /* fall through */
                        case PEER_SESS_ST_GETVERSION:
                                prev_state = appctx->st0;
-                               reql = co_getline(si_oc(si), trash.area,
-                                                 trash.size);
-                               if (reql <= 0) { /* closed or EOL not found */
-                                       if (reql == 0)
-                                               goto out;
-                                       appctx->st0 = PEER_SESS_ST_END;
-                                       goto switchstate;
-                               }
-                               if (trash.area[reql-1] != '\n') {
-                                       appctx->st0 = PEER_SESS_ST_END;
-                                       goto switchstate;
-                               }
-                               else if (reql > 1 && (trash.area[reql-2] == '\r'))
-                                       trash.area[reql-2] = 0;
-                               else
-                                       trash.area[reql-1] = 0;
 
-                               co_skip(si_oc(si), reql);
+                               reql = peer_getline(appctx);
+                               if (!reql)
+                                       goto out;
+
+                               if (reql < 0)
+                                       goto switchstate;
 
                                /* test protocol */
                                if (strncmp(PEER_SESSION_PROTO_NAME " ", trash.area, proto_len + 1) != 0) {
@@ -628,24 +647,13 @@ switchstate:
                                /* fall through */
                        case PEER_SESS_ST_GETHOST:
                                prev_state = appctx->st0;
-                               reql = co_getline(si_oc(si), trash.area,
-                                                 trash.size);
-                               if (reql <= 0) { /* closed or EOL not found */
-                                       if (reql == 0)
-                                               goto out;
-                                       appctx->st0 = PEER_SESS_ST_END;
-                                       goto switchstate;
-                               }
-                               if (trash.area[reql-1] != '\n') {
-                                       appctx->st0 = PEER_SESS_ST_END;
-                                       goto switchstate;
-                               }
-                               else if (reql > 1 && (trash.area[reql-2] == '\r'))
-                                       trash.area[reql-2] = 0;
-                               else
-                                       trash.area[reql-1] = 0;
 
-                               co_skip(si_oc(si), reql);
+                               reql = peer_getline(appctx);
+                               if (!reql)
+                                       goto out;
+
+                               if (reql < 0)
+                                       goto switchstate;
 
                                /* test hostname match */
                                if (strcmp(localpeer, trash.area) != 0) {
@@ -660,25 +668,13 @@ switchstate:
                                char *p;
 
                                prev_state = appctx->st0;
-                               reql = co_getline(si_oc(si), trash.area,
-                                                 trash.size);
-                               if (reql <= 0) { /* closed or EOL not found */
-                                       if (reql == 0)
-                                               goto out;
-                                       appctx->st0 = PEER_SESS_ST_END;
-                                       goto switchstate;
-                               }
-                               if (trash.area[reql-1] != '\n') {
-                                       /* Incomplete line, we quit */
-                                       appctx->st0 = PEER_SESS_ST_END;
-                                       goto switchstate;
-                               }
-                               else if (reql > 1 && (trash.area[reql-2] == '\r'))
-                                       trash.area[reql-2] = 0;
-                               else
-                                       trash.area[reql-1] = 0;
 
-                               co_skip(si_oc(si), reql);
+                               reql = peer_getline(appctx);
+                               if (!reql)
+                                       goto out;
+
+                               if (reql < 0)
+                                       goto switchstate;
 
                                /* parse line "<peer name> <pid> <relative_pid>" */
                                p = strchr(trash.area, ' ');
@@ -852,25 +848,12 @@ switchstate:
                                if (si_ic(si)->flags & CF_WRITE_PARTIAL)
                                        curpeer->statuscode = PEER_SESS_SC_CONNECTEDCODE;
 
-                               reql = co_getline(si_oc(si), trash.area,
-                                                 trash.size);
-                               if (reql <= 0) { /* closed or EOL not found */
-                                       if (reql == 0)
-                                               goto out;
-                                       appctx->st0 = PEER_SESS_ST_END;
-                                       goto switchstate;
-                               }
-                               if (trash.area[reql-1] != '\n') {
-                                       /* Incomplete line, we quit */
-                                       appctx->st0 = PEER_SESS_ST_END;
-                                       goto switchstate;
-                               }
-                               else if (reql > 1 && (trash.area[reql-2] == '\r'))
-                                       trash.area[reql-2] = 0;
-                               else
-                                       trash.area[reql-1] = 0;
+                               reql = peer_getline(appctx);
+                               if (!reql)
+                                       goto out;
 
-                               co_skip(si_oc(si), reql);
+                               if (reql < 0)
+                                       goto switchstate;
 
                                /* Register status code */
                                curpeer->statuscode = atoi(trash.area);