Start a handshake with the specified address if there is not one * already in progress. Returns non-zero if the handshake was actually * started. On error zero is returned and errno is set to one of the * following values: * * EAGAIN - There is already a handshake in progress for this address. * EINVAL - IP or port are not valid. */
| 1411 | * EAGAIN - There is already a handshake in progress for this address. |
| 1412 | * EINVAL - IP or port are not valid. */ |
| 1413 | int clusterStartHandshake(char *ip, int port, int cport) { |
| 1414 | clusterNode *n; |
| 1415 | char norm_ip[NET_IP_STR_LEN]; |
| 1416 | struct sockaddr_storage sa; |
| 1417 | |
| 1418 | /* IP sanity check */ |
| 1419 | if (inet_pton(AF_INET,ip, |
| 1420 | &(((struct sockaddr_in *)&sa)->sin_addr))) |
| 1421 | { |
| 1422 | sa.ss_family = AF_INET; |
| 1423 | } else if (inet_pton(AF_INET6,ip, |
| 1424 | &(((struct sockaddr_in6 *)&sa)->sin6_addr))) |
| 1425 | { |
| 1426 | sa.ss_family = AF_INET6; |
| 1427 | } else { |
| 1428 | errno = EINVAL; |
| 1429 | return 0; |
| 1430 | } |
| 1431 | |
| 1432 | /* Port sanity check */ |
| 1433 | if (port <= 0 || port > 65535 || cport <= 0 || cport > 65535) { |
| 1434 | errno = EINVAL; |
| 1435 | return 0; |
| 1436 | } |
| 1437 | |
| 1438 | /* Set norm_ip as the normalized string representation of the node |
| 1439 | * IP address. */ |
| 1440 | memset(norm_ip,0,NET_IP_STR_LEN); |
| 1441 | if (sa.ss_family == AF_INET) |
| 1442 | inet_ntop(AF_INET, |
| 1443 | (void*)&(((struct sockaddr_in *)&sa)->sin_addr), |
| 1444 | norm_ip,NET_IP_STR_LEN); |
| 1445 | else |
| 1446 | inet_ntop(AF_INET6, |
| 1447 | (void*)&(((struct sockaddr_in6 *)&sa)->sin6_addr), |
| 1448 | norm_ip,NET_IP_STR_LEN); |
| 1449 | |
| 1450 | if (clusterHandshakeInProgress(norm_ip,port,cport)) { |
| 1451 | errno = EAGAIN; |
| 1452 | return 0; |
| 1453 | } |
| 1454 | |
| 1455 | /* Add the node with a random address (NULL as first argument to |
| 1456 | * createClusterNode()). Everything will be fixed during the |
| 1457 | * handshake. */ |
| 1458 | n = createClusterNode(NULL,CLUSTER_NODE_HANDSHAKE|CLUSTER_NODE_MEET); |
| 1459 | memcpy(n->ip,norm_ip,sizeof(n->ip)); |
| 1460 | n->port = port; |
| 1461 | n->cport = cport; |
| 1462 | clusterAddNode(n); |
| 1463 | return 1; |
| 1464 | } |
| 1465 | |
| 1466 | /* Process the gossip section of PING or PONG packets. |
| 1467 | * Note that this function assumes that the packet is already sanity-checked |
no test coverage detected