Read data. Try to read the first field of the header first to check the * full length of the packet. When a whole packet is in memory this function * will call the function to process the packet. And so forth. */
| 2318 | * full length of the packet. When a whole packet is in memory this function |
| 2319 | * will call the function to process the packet. And so forth. */ |
| 2320 | void clusterReadHandler(connection *conn) { |
| 2321 | clusterMsg buf[1]; |
| 2322 | ssize_t nread; |
| 2323 | clusterMsg *hdr; |
| 2324 | clusterLink *link = connGetPrivateData(conn); |
| 2325 | unsigned int readlen, rcvbuflen; |
| 2326 | |
| 2327 | while(1) { /* Read as long as there is data to read. */ |
| 2328 | rcvbuflen = link->rcvbuf_len; |
| 2329 | if (rcvbuflen < 8) { |
| 2330 | /* First, obtain the first 8 bytes to get the full message |
| 2331 | * length. */ |
| 2332 | readlen = 8 - rcvbuflen; |
| 2333 | } else { |
| 2334 | /* Finally read the full message. */ |
| 2335 | hdr = (clusterMsg*) link->rcvbuf; |
| 2336 | if (rcvbuflen == 8) { |
| 2337 | /* Perform some sanity check on the message signature |
| 2338 | * and length. */ |
| 2339 | if (memcmp(hdr->sig,"RCmb",4) != 0 || |
| 2340 | ntohl(hdr->totlen) < CLUSTERMSG_MIN_LEN) |
| 2341 | { |
| 2342 | serverLog(LL_WARNING, |
| 2343 | "Bad message length or signature received " |
| 2344 | "from Cluster bus."); |
| 2345 | handleLinkIOError(link); |
| 2346 | return; |
| 2347 | } |
| 2348 | } |
| 2349 | readlen = ntohl(hdr->totlen) - rcvbuflen; |
| 2350 | if (readlen > sizeof(buf)) readlen = sizeof(buf); |
| 2351 | } |
| 2352 | |
| 2353 | nread = connRead(conn,buf,readlen); |
| 2354 | if (nread == -1 && (connGetState(conn) == CONN_STATE_CONNECTED)) return; /* No more data ready. */ |
| 2355 | |
| 2356 | if (nread <= 0) { |
| 2357 | /* I/O error... */ |
| 2358 | serverLog(LL_DEBUG,"I/O error reading from node link: %s", |
| 2359 | (nread == 0) ? "connection closed" : connGetLastError(conn)); |
| 2360 | handleLinkIOError(link); |
| 2361 | return; |
| 2362 | } else { |
| 2363 | /* Read data and recast the pointer to the new buffer. */ |
| 2364 | size_t unused = link->rcvbuf_alloc - link->rcvbuf_len; |
| 2365 | if ((size_t)nread > unused) { |
| 2366 | size_t required = link->rcvbuf_len + nread; |
| 2367 | /* If less than 1mb, grow to twice the needed size, if larger grow by 1mb. */ |
| 2368 | link->rcvbuf_alloc = required < RCVBUF_MAX_PREALLOC ? required * 2: required + RCVBUF_MAX_PREALLOC; |
| 2369 | link->rcvbuf = zrealloc(link->rcvbuf, link->rcvbuf_alloc); |
| 2370 | } |
| 2371 | memcpy(link->rcvbuf + link->rcvbuf_len, buf, nread); |
| 2372 | link->rcvbuf_len += nread; |
| 2373 | hdr = (clusterMsg*) link->rcvbuf; |
| 2374 | rcvbuflen += nread; |
| 2375 | } |
| 2376 | |
| 2377 | /* Total length obtained? Process this packet. */ |
nothing calls this directly
no test coverage detected