| 1471 | |
| 1472 | |
| 1473 | void SocketManager::link_connect( |
| 1474 | const Future<Nothing>& future, |
| 1475 | Socket socket, |
| 1476 | const UPID& to) |
| 1477 | { |
| 1478 | if (future.isDiscarded() || future.isFailed()) { |
| 1479 | if (future.isFailed()) { |
| 1480 | LOG(WARNING) << "Failed to link to '" << to.address |
| 1481 | << "', connect: " << future.failure(); |
| 1482 | } |
| 1483 | |
| 1484 | // Check if SSL is enabled, and whether we allow a downgrade to |
| 1485 | // non-SSL traffic. |
| 1486 | #ifdef USE_SSL_SOCKET |
| 1487 | bool attempt_downgrade = |
| 1488 | future.isFailed() && |
| 1489 | network::openssl::flags().enabled && |
| 1490 | network::openssl::flags().support_downgrade && |
| 1491 | socket.kind() == SocketImpl::Kind::SSL; |
| 1492 | |
| 1493 | Option<Socket> poll_socket = None(); |
| 1494 | |
| 1495 | // If we allow downgrading from SSL to non-SSL, then retry as a |
| 1496 | // POLL socket. |
| 1497 | if (attempt_downgrade) { |
| 1498 | synchronized (mutex) { |
| 1499 | // It is possible that a prior call to `link()` with `RECONNECT` |
| 1500 | // semantics has swapped out this socket before we finished |
| 1501 | // connecting. In this case, we simply stop here and allow the |
| 1502 | // latest created socket to complete the link. |
| 1503 | if (sockets.count(socket) <= 0) { |
| 1504 | return; |
| 1505 | } |
| 1506 | |
| 1507 | Try<Socket> create = Socket::create(SocketImpl::Kind::POLL); |
| 1508 | if (create.isError()) { |
| 1509 | LOG(WARNING) << "Failed to link to '" << to.address |
| 1510 | << "', create socket: " << create.error(); |
| 1511 | socket_manager->close(socket); |
| 1512 | return; |
| 1513 | } |
| 1514 | |
| 1515 | poll_socket = create.get(); |
| 1516 | |
| 1517 | // Update all the data structures that are mapped to the socket |
| 1518 | // that just failed to connect. They will now point to the new |
| 1519 | // POLL socket we are about to try to connect. Even if the |
| 1520 | // process has exited, persistent links will stay around, and |
| 1521 | // temporary links will get cleaned up as they would otherwise. |
| 1522 | swap_implementing_socket(socket, poll_socket.get()); |
| 1523 | } |
| 1524 | |
| 1525 | CHECK_SOME(poll_socket); |
| 1526 | poll_socket->connect(to.address) |
| 1527 | .onAny(lambda::bind( |
| 1528 | &SocketManager::link_connect, |
| 1529 | this, |
| 1530 | lambda::_1, |