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. */
| 1468 | * by the caller, not in the content of the gossip section, but in the |
| 1469 | * length. */ |
| 1470 | void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { |
| 1471 | uint16_t count = ntohs(hdr->count); |
| 1472 | clusterMsgDataGossip *g = (clusterMsgDataGossip*) hdr->data.ping.gossip; |
| 1473 | clusterNode *sender = link->node ? link->node : clusterLookupNode(hdr->sender); |
| 1474 | |
| 1475 | while(count--) { |
| 1476 | uint16_t flags = ntohs(g->flags); |
| 1477 | clusterNode *node; |
| 1478 | sds ci; |
| 1479 | |
| 1480 | if (cserver.verbosity == LL_DEBUG) { |
| 1481 | ci = representClusterNodeFlags(sdsempty(), flags); |
| 1482 | serverLog(LL_DEBUG,"GOSSIP %.40s %s:%d@%d %s", |
| 1483 | g->nodename, |
| 1484 | g->ip, |
| 1485 | ntohs(g->port), |
| 1486 | ntohs(g->cport), |
| 1487 | ci); |
| 1488 | sdsfree(ci); |
| 1489 | } |
| 1490 | |
| 1491 | /* Update our state accordingly to the gossip sections */ |
| 1492 | node = clusterLookupNode(g->nodename); |
| 1493 | if (node) { |
| 1494 | /* We already know this node. |
| 1495 | Handle failure reports, only when the sender is a master. */ |
| 1496 | if (sender && nodeIsMaster(sender) && node != myself) { |
| 1497 | if (flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_PFAIL)) { |
| 1498 | if (clusterNodeAddFailureReport(node,sender)) { |
| 1499 | serverLog(LL_VERBOSE, |
| 1500 | "Node %.40s reported node %.40s as not reachable.", |
| 1501 | sender->name, node->name); |
| 1502 | } |
| 1503 | markNodeAsFailingIfNeeded(node); |
| 1504 | } else { |
| 1505 | if (clusterNodeDelFailureReport(node,sender)) { |
| 1506 | serverLog(LL_VERBOSE, |
| 1507 | "Node %.40s reported node %.40s is back online.", |
| 1508 | sender->name, node->name); |
| 1509 | } |
| 1510 | } |
| 1511 | } |
| 1512 | |
| 1513 | /* If from our POV the node is up (no failure flags are set), |
| 1514 | * we have no pending ping for the node, nor we have failure |
| 1515 | * reports for this node, update the last pong time with the |
| 1516 | * one we see from the other nodes. */ |
| 1517 | if (!(flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_PFAIL)) && |
| 1518 | node->ping_sent == 0 && |
| 1519 | clusterNodeFailureReportsCount(node) == 0) |
| 1520 | { |
| 1521 | mstime_t pongtime = ntohl(g->pong_received); |
| 1522 | pongtime *= 1000; /* Convert back to milliseconds. */ |
| 1523 | |
| 1524 | /* Replace the pong time with the received one only if |
| 1525 | * it's greater than our view but is not in the future |
| 1526 | * (with 500 milliseconds tolerance) from the POV of our |
| 1527 | * clock. */ |
no test coverage detected