| 248 | } |
| 249 | |
| 250 | int8_t Socket::createConnection(const addrinfo* const destination_addresses) { |
| 251 | for (const auto *current_addr = destination_addresses; current_addr; current_addr = current_addr->ai_next) { |
| 252 | if (!valid_socket(socket_file_descriptor_ = socket(current_addr->ai_family, current_addr->ai_socktype, current_addr->ai_protocol))) { |
| 253 | logger_->log_warn("socket: %s", get_last_socket_error_message()); |
| 254 | continue; |
| 255 | } |
| 256 | setSocketOptions(socket_file_descriptor_); |
| 257 | |
| 258 | if (listeners_ > 0) { |
| 259 | // server socket |
| 260 | const auto bind_result = bind(socket_file_descriptor_, current_addr->ai_addr, current_addr->ai_addrlen); |
| 261 | if (bind_result == SOCKET_ERROR) { |
| 262 | logger_->log_warn("bind: %s", get_last_socket_error_message()); |
| 263 | close(); |
| 264 | continue; |
| 265 | } |
| 266 | |
| 267 | const auto listen_result = listen(socket_file_descriptor_, listeners_); |
| 268 | if (listen_result == SOCKET_ERROR) { |
| 269 | logger_->log_warn("listen: %s", get_last_socket_error_message()); |
| 270 | close(); |
| 271 | continue; |
| 272 | } |
| 273 | |
| 274 | logger_->log_info("Listening on %s:%" PRIu16 " with backlog %" PRIu16, sockaddr_ntop(current_addr->ai_addr), port_, listeners_); |
| 275 | } else { |
| 276 | // client socket |
| 277 | #ifndef WIN32 |
| 278 | if (!local_network_interface_.getInterface().empty()) { |
| 279 | const auto err = bind_to_local_network_interface(socket_file_descriptor_, local_network_interface_); |
| 280 | if (err) logger_->log_info("Bind to interface %s failed %s", local_network_interface_.getInterface(), err.message()); |
| 281 | else logger_->log_info("Bind to interface %s", local_network_interface_.getInterface()); |
| 282 | } |
| 283 | #endif /* !WIN32 */ |
| 284 | |
| 285 | const auto connect_result = connect(socket_file_descriptor_, current_addr->ai_addr, current_addr->ai_addrlen); |
| 286 | if (connect_result == SOCKET_ERROR) { |
| 287 | logger_->log_warn("Couldn't connect to %s:%" PRIu16 ": %s", sockaddr_ntop(current_addr->ai_addr), port_, get_last_socket_error_message()); |
| 288 | close(); |
| 289 | continue; |
| 290 | } |
| 291 | |
| 292 | logger_->log_info("Connected to %s:%" PRIu16, sockaddr_ntop(current_addr->ai_addr), port_); |
| 293 | } |
| 294 | |
| 295 | FD_SET(socket_file_descriptor_, &total_list_); |
| 296 | socket_max_ = socket_file_descriptor_; |
| 297 | return 0; |
| 298 | } |
| 299 | return -1; |
| 300 | } |
| 301 | |
| 302 | int8_t Socket::createConnection(const addrinfo *, ip4addr &addr) { |
| 303 | if (!valid_socket(socket_file_descriptor_ = socket(AF_INET, SOCK_STREAM, 0))) { |
nothing calls this directly
no test coverage detected