Process the gossip section of PING or PONG packets. * Note that this function assumes that the packet is already sanity-checked * by the caller, not in the content of the gossip section, but in the * length. */
| 1429 | * by the caller, not in the content of the gossip section, but in the |
| 1430 | * length. */ |
| 1431 | void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { |
| 1432 | uint16_t count = ntohs(hdr->count); |
| 1433 | clusterMsgDataGossip *g = (clusterMsgDataGossip*) hdr->data.ping.gossip; |
| 1434 | clusterNode *sender = link->node ? link->node : clusterLookupNode(hdr->sender); |
| 1435 | |
| 1436 | while(count--) { |
| 1437 | uint16_t flags = ntohs(g->flags); |
| 1438 | clusterNode *node; |
| 1439 | sds ci; |
| 1440 | |
| 1441 | if (server.verbosity == LL_DEBUG) { |
| 1442 | ci = representClusterNodeFlags(sdsempty(), flags); |
| 1443 | serverLog(LL_DEBUG,"GOSSIP %.40s %s:%d@%d %s", |
| 1444 | g->nodename, |
| 1445 | g->ip, |
| 1446 | ntohs(g->port), |
| 1447 | ntohs(g->cport), |
| 1448 | ci); |
| 1449 | sdsfree(ci); |
| 1450 | } |
| 1451 | |
| 1452 | /* Update our state accordingly to the gossip sections */ |
| 1453 | node = clusterLookupNode(g->nodename); |
| 1454 | if (node) { |
| 1455 | /* We already know this node. |
| 1456 | Handle failure reports, only when the sender is a master. */ |
| 1457 | if (sender && nodeIsMaster(sender) && node != myself) { |
| 1458 | if (flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_PFAIL)) { |
| 1459 | if (clusterNodeAddFailureReport(node,sender)) { |
| 1460 | serverLog(LL_VERBOSE, |
| 1461 | "Node %.40s reported node %.40s as not reachable.", |
| 1462 | sender->name, node->name); |
| 1463 | } |
| 1464 | markNodeAsFailingIfNeeded(node); |
| 1465 | } else { |
| 1466 | if (clusterNodeDelFailureReport(node,sender)) { |
| 1467 | serverLog(LL_VERBOSE, |
| 1468 | "Node %.40s reported node %.40s is back online.", |
| 1469 | sender->name, node->name); |
| 1470 | } |
| 1471 | } |
| 1472 | } |
| 1473 | |
| 1474 | /* If from our POV the node is up (no failure flags are set), |
| 1475 | * we have no pending ping for the node, nor we have failure |
| 1476 | * reports for this node, update the last pong time with the |
| 1477 | * one we see from the other nodes. */ |
| 1478 | if (!(flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_PFAIL)) && |
| 1479 | node->ping_sent == 0 && |
| 1480 | clusterNodeFailureReportsCount(node) == 0) |
| 1481 | { |
| 1482 | mstime_t pongtime = ntohl(g->pong_received); |
| 1483 | pongtime *= 1000; /* Convert back to milliseconds. */ |
| 1484 | |
| 1485 | /* Replace the pong time with the received one only if |
| 1486 | * it's greater than our view but is not in the future |
| 1487 | * (with 500 milliseconds tolerance) from the POV of our |
| 1488 | * clock. */ |
no test coverage detected