MCPcopy Create free account
hub / github.com/3rdparty/libprocess / connect

Function connect

src/windows/libwinio.cpp:636–699  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

634
635
636Future<Nothing> connect(const int_fd& fd, const network::Address& address)
637{
638 process::initialize();
639
640 // `::ConnectEx` needs the socket to be bound first.
641 Try<Nothing> bind_result = Nothing();
642 if (address.family() == network::Address::Family::INET4) {
643 const network::inet4::Address addr = network::inet4::Address::ANY_ANY();
644 bind_result = network::bind(fd, addr);
645 } else if (address.family() == network::Address::Family::INET6) {
646 const network::inet6::Address addr = network::inet6::Address::ANY_ANY();
647 bind_result = network::bind(fd, addr);
648 } else {
649 return Failure("Async connect only supports IPv6 and IPv4");
650 }
651
652 if (bind_result.isError()) {
653 // `WSAEINVAL` means socket is already bound, so we can continue. If it was
654 // bound incorrectly, then we can get an error later on.
655 if (::WSAGetLastError() != WSAEINVAL) {
656 return Failure("Failed to bind connect socket: " + bind_result.error());
657 }
658 }
659
660 // Load `::ConnectEx` function pointer, since it's not normally available.
661 const sockaddr_storage storage = address;
662 const int address_size = static_cast<int>(address.size());
663 LPFN_CONNECTEX connect_ex = get_connect_ex_ptr(fd);
664
665 Promise<Nothing>* promise = new Promise<Nothing>();
666 Future<Nothing> future = promise->future();
667
668 auto overlapped = std::make_shared<IOOverlappedConnect>(
669 IOOverlappedBase{OVERLAPPED{}, fd, IOType::CONNECT}, promise);
670
671 enable_cancellation(fd, future, overlapped);
672
673 const BOOL success = connect_ex(
674 fd,
675 reinterpret_cast<const sockaddr*>(&storage),
676 address_size,
677 nullptr,
678 0,
679 nullptr,
680 &overlapped->base.overlapped);
681
682 const DWORD error = ::WSAGetLastError();
683
684 // If the request is pending, then we return immediately and have the
685 // callback free the promise and overlapped
686 if (!success && error == WSA_IO_PENDING) {
687 return future;
688 }
689
690 // In an error or immediate success, we have to manually set the promise
691 // and free it.
692 if (success) {
693 promise->set(Nothing());

Callers 5

connectMethod · 0.70
connectMethod · 0.50
TEST_FFunction · 0.50
TESTFunction · 0.50
TEST_FFunction · 0.50

Calls 9

bindFunction · 0.85
FailureClass · 0.85
enable_cancellationFunction · 0.85
familyMethod · 0.80
futureMethod · 0.80
initializeFunction · 0.50
sizeMethod · 0.45
setMethod · 0.45
failMethod · 0.45

Tested by 3

TEST_FFunction · 0.40
TESTFunction · 0.40
TEST_FFunction · 0.40