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. */
| 1372 | * EAGAIN - There is already a handshake in progress for this address. |
| 1373 | * EINVAL - IP or port are not valid. */ |
| 1374 | int clusterStartHandshake(char *ip, int port, int cport) { |
| 1375 | clusterNode *n; |
| 1376 | char norm_ip[NET_IP_STR_LEN]; |
| 1377 | struct sockaddr_storage sa; |
| 1378 | |
| 1379 | /* IP sanity check */ |
| 1380 | if (inet_pton(AF_INET,ip, |
| 1381 | &(((struct sockaddr_in *)&sa)->sin_addr))) |
| 1382 | { |
| 1383 | sa.ss_family = AF_INET; |
| 1384 | } else if (inet_pton(AF_INET6,ip, |
| 1385 | &(((struct sockaddr_in6 *)&sa)->sin6_addr))) |
| 1386 | { |
| 1387 | sa.ss_family = AF_INET6; |
| 1388 | } else { |
| 1389 | errno = EINVAL; |
| 1390 | return 0; |
| 1391 | } |
| 1392 | |
| 1393 | /* Port sanity check */ |
| 1394 | if (port <= 0 || port > 65535 || cport <= 0 || cport > 65535) { |
| 1395 | errno = EINVAL; |
| 1396 | return 0; |
| 1397 | } |
| 1398 | |
| 1399 | /* Set norm_ip as the normalized string representation of the node |
| 1400 | * IP address. */ |
| 1401 | memset(norm_ip,0,NET_IP_STR_LEN); |
| 1402 | if (sa.ss_family == AF_INET) |
| 1403 | inet_ntop(AF_INET, |
| 1404 | (void*)&(((struct sockaddr_in *)&sa)->sin_addr), |
| 1405 | norm_ip,NET_IP_STR_LEN); |
| 1406 | else |
| 1407 | inet_ntop(AF_INET6, |
| 1408 | (void*)&(((struct sockaddr_in6 *)&sa)->sin6_addr), |
| 1409 | norm_ip,NET_IP_STR_LEN); |
| 1410 | |
| 1411 | if (clusterHandshakeInProgress(norm_ip,port,cport)) { |
| 1412 | errno = EAGAIN; |
| 1413 | return 0; |
| 1414 | } |
| 1415 | |
| 1416 | /* Add the node with a random address (NULL as first argument to |
| 1417 | * createClusterNode()). Everything will be fixed during the |
| 1418 | * handshake. */ |
| 1419 | n = createClusterNode(NULL,CLUSTER_NODE_HANDSHAKE|CLUSTER_NODE_MEET); |
| 1420 | memcpy(n->ip,norm_ip,sizeof(n->ip)); |
| 1421 | n->port = port; |
| 1422 | n->cport = cport; |
| 1423 | clusterAddNode(n); |
| 1424 | return 1; |
| 1425 | } |
| 1426 | |
| 1427 | /* Process the gossip section of PING or PONG packets. |
| 1428 | * Note that this function assumes that the packet is already sanity-checked |
no test coverage detected