diff --git a/src/Cedar/Protocol.c b/src/Cedar/Protocol.c index b61abc1e..7efd3397 100644 --- a/src/Cedar/Protocol.c +++ b/src/Cedar/Protocol.c @@ -5429,7 +5429,7 @@ void ClientUploadNoop(CONNECTION *c) } p = PackError(0); - PackAddInt(p, "noop", 1); + PackAddInt(p, "noop", NOOP); (void)HttpClientSend(c->FirstSock, p); FreePack(p); @@ -5440,6 +5440,24 @@ void ClientUploadNoop(CONNECTION *c) } } +void ServerUploadNoop(CONNECTION *c) +{ + PACK *p; + // Validate arguments + if (c == NULL) + { + return; + } + + p = PackError(0); + PackAddInt(p, "noop", NOOP_IGNORE); + (void)HttpServerSend(c->FirstSock, p); + FreePack(p); + + // Client can't re-respond to an HTTP "response" + // so we don't wait for it on the server side +} + // Add client version information to the PACK void PackAddClientVersion(PACK *p, CONNECTION *c) { diff --git a/src/Cedar/Protocol.h b/src/Cedar/Protocol.h index 112b365a..ac982767 100644 --- a/src/Cedar/Protocol.h +++ b/src/Cedar/Protocol.h @@ -169,6 +169,7 @@ bool GetSessionKeyFromPack(PACK *p, UCHAR *session_key, UINT *session_key_32); void CreateNodeInfo(NODE_INFO *info, CONNECTION *c); UINT SecureSign(SECURE_SIGN *sign, UINT device_id, char *pin); void ClientUploadNoop(CONNECTION *c); +void ServerUploadNoop(CONNECTION *c); bool ClientCheckServerCert(CONNECTION *c, bool *expired); void ClientCheckServerCertThread(THREAD *thread, void *param); bool ClientSecureSign(CONNECTION *c, UCHAR *sign, UCHAR *random, X **x); diff --git a/src/Mayaqua/HTTP.c b/src/Mayaqua/HTTP.c index 22ace11b..ba6dcc23 100644 --- a/src/Mayaqua/HTTP.c +++ b/src/Mayaqua/HTTP.c @@ -1207,12 +1207,14 @@ PACK *HttpClientRecv(SOCK *s) UINT size; UCHAR *tmp; HTTP_VALUE *v; + UINT num_noop = 0; // Validate arguments if (s == NULL) { return NULL; } +START: h = RecvHttpHeader(s); if (h == NULL) { @@ -1257,6 +1259,22 @@ PACK *HttpClientRecv(SOCK *s) p = BufToPack(b); FreeBuf(b); + // Client shouldn't receive a noop other than NOOP_IGNORE + // because it can't respond without a full new HTTP request + UINT noop = PackGetInt(p, "noop"); + if (noop == NOOP_IGNORE) { + Debug("recv: noop ignore\n"); + FreePack(p); + + num_noop++; + + if (num_noop > MAX_NOOP_PER_SESSION) + { + return NULL; + } + + goto START; + } return p; } @@ -1365,13 +1383,14 @@ START: FreeBuf(b); // Determine whether it's a NOOP - if (PackGetInt(p, "noop") != 0) + UINT noop = PackGetInt(p, "noop"); + if (noop == NOOP) { Debug("recv: noop\n"); FreePack(p); p = PackError(0); - PackAddInt(p, "noop", 1); + PackAddInt(p, "noop", NOOP_IGNORE); if (HttpServerSend(s, p) == false) { FreePack(p); @@ -1387,6 +1406,11 @@ START: return NULL; } + goto START; + } else if (noop == NOOP_IGNORE) { + Debug("recv: noop ignore\n"); + FreePack(p); + goto START; } diff --git a/src/Mayaqua/Pack.h b/src/Mayaqua/Pack.h index 1f93cd58..ef3cffe1 100644 --- a/src/Mayaqua/Pack.h +++ b/src/Mayaqua/Pack.h @@ -38,6 +38,8 @@ // The number of allowable NOOP #define MAX_NOOP_PER_SESSION 30 +#define NOOP 1 +#define NOOP_IGNORE 2 // A noop, but don't send a response noop // VALUE object struct VALUE