65 lines
1.7 KiB
C++
65 lines
1.7 KiB
C++
#include "flow_help.h"
|
|
#include "ssl.h"
|
|
#include <arpa/inet.h>
|
|
#include <cerrno>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <iostream>
|
|
#include <netdb.h>
|
|
#include <netinet/in.h>
|
|
#include <openssl/err.h>
|
|
#include <openssl/ssl.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <string>
|
|
#include <sys/socket.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
|
|
namespace pupes_message_client_lib {
|
|
int create_socket_and_connect(const char *hostname, const char *port) {
|
|
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
|
if (sockfd < 0)
|
|
error("Socket creation failed");
|
|
|
|
// Set up server address
|
|
struct sockaddr_storage serv_addr;
|
|
memset(&serv_addr, 0, sizeof(serv_addr));
|
|
|
|
struct addrinfo hints, *res;
|
|
memset(&hints, 0, sizeof(hints));
|
|
hints.ai_family = AF_UNSPEC; // Enable IPv4/IPv6 dual support
|
|
hints.ai_socktype = SOCK_STREAM;
|
|
|
|
// Resolve hostname and port together
|
|
int status = getaddrinfo(hostname, port, &hints, &res);
|
|
if (status != 0) {
|
|
std::cerr << "Resolution failed: " << gai_strerror(status) << "\n";
|
|
std::exit(EINVAL);
|
|
}
|
|
|
|
// Try all addresses until successful connection
|
|
struct addrinfo *rp;
|
|
for (rp = res; rp != NULL; rp = rp->ai_next) {
|
|
sockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
|
if (sockfd == -1)
|
|
continue;
|
|
|
|
if (connect(sockfd, rp->ai_addr, rp->ai_addrlen) == 0)
|
|
break; // Success
|
|
|
|
close(sockfd);
|
|
sockfd = -1;
|
|
}
|
|
freeaddrinfo(res); // Free after connection attempts
|
|
|
|
if (sockfd == -1) {
|
|
std::cerr << "Failed to connect to all resolved addresses\n";
|
|
freeaddrinfo(res);
|
|
error("Connection failed");
|
|
}
|
|
printf("Connected to %s:%s\n", hostname, port);
|
|
return sockfd;
|
|
}
|
|
} // namespace pupes_message_client_lib
|