ascii-chat 0.11.33
Video chat in your terminal
Loading...
Searching...
No Matches
connection_factory.c
Go to the documentation of this file.
1
7
8#include <ascii-chat/common.h>
12
13#ifdef _WIN32
14#include <ws2tcpip.h>
15#else
16#include <netdb.h>
17#include <sys/socket.h>
18#endif
19
20#include <string.h>
21
22static asciichat_error_t connection_factory_open_tcp(const char *name, const connection_endpoint_t *endpoint,
23 crypto_context_t *crypto_ctx, acip_transport_t **transport_out) {
24 struct addrinfo hints;
25 struct addrinfo *addr_result = NULL;
26 struct addrinfo *addr_iter = NULL;
27 char port_str[16];
29
30 memset(&hints, 0, sizeof(hints));
31 hints.ai_family = AF_UNSPEC;
32 hints.ai_socktype = SOCK_STREAM;
33 hints.ai_protocol = IPPROTO_TCP;
34
35 safe_snprintf(port_str, sizeof(port_str), "%u", endpoint->port);
36
37 int gai_result = getaddrinfo(endpoint->host, port_str, &hints, &addr_result);
38 if (gai_result != 0) {
39 log_error("Failed to resolve TCP endpoint %s:%u: %s", endpoint->host, endpoint->port, gai_strerror(gai_result));
40 return SET_ERRNO(ERROR_NETWORK_CONNECT, "Failed to resolve TCP endpoint");
41 }
42
43 for (addr_iter = addr_result; addr_iter != NULL; addr_iter = addr_iter->ai_next) {
44 sockfd = socket(addr_iter->ai_family, addr_iter->ai_socktype, addr_iter->ai_protocol);
45 if (sockfd == INVALID_SOCKET_VALUE) {
46 continue;
47 }
48
49 if (connect_with_timeout(sockfd, addr_iter->ai_addr, addr_iter->ai_addrlen, CONNECT_TIMEOUT)) {
50 break;
51 }
52
53 socket_close(sockfd);
54 sockfd = INVALID_SOCKET_VALUE;
55 }
56
57 freeaddrinfo(addr_result);
58
59 if (sockfd == INVALID_SOCKET_VALUE) {
60 log_error("Failed to connect to TCP endpoint %s:%u", endpoint->host, endpoint->port);
61 return SET_ERRNO(ERROR_NETWORK_CONNECT, "Failed to connect to TCP endpoint");
62 }
63
64 acip_transport_t *transport = acip_tcp_transport_create(name, sockfd, crypto_ctx);
65 if (!transport) {
66 log_error("Failed to create TCP transport for %s:%u", endpoint->host, endpoint->port);
67 socket_close(sockfd);
68 return SET_ERRNO(ERROR_NETWORK, "Failed to create TCP transport");
69 }
70
71 *transport_out = transport;
72 return ASCIICHAT_OK;
73}
74
75asciichat_error_t connection_factory_open(const char *name, const char *input, uint16_t default_port,
76 crypto_context_t *crypto_ctx, acip_transport_t **transport_out,
77 connection_endpoint_t *endpoint_out) {
78 if (!name || !input || !transport_out) {
79 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid connection factory parameters");
80 }
81
82 *transport_out = NULL;
83
84 connection_endpoint_t endpoint = {0};
85 asciichat_error_t resolve_result = connection_endpoint_resolve(input, default_port, &endpoint);
86 if (resolve_result != ASCIICHAT_OK) {
87 return resolve_result;
88 }
89
90 acip_transport_t *transport = NULL;
91
92 switch (endpoint.protocol) {
94 transport = acip_websocket_client_transport_create(name, endpoint.input, crypto_ctx);
95 if (!transport) {
96 return SET_ERRNO(ERROR_NETWORK_CONNECT, "Failed to create WebSocket transport");
97 }
98 break;
99
101 resolve_result = connection_factory_open_tcp(name, &endpoint, crypto_ctx, &transport);
102 if (resolve_result != ASCIICHAT_OK) {
103 return resolve_result;
104 }
105 break;
106
107 default:
108 return SET_ERRNO(ERROR_INVALID_PARAM, "Unsupported endpoint protocol");
109 }
110
111 if (endpoint_out) {
112 *endpoint_out = endpoint;
113 }
114 *transport_out = transport;
115 return ASCIICHAT_OK;
116}
Platform abstraction layer umbrella header providing unified cross-platform API.
⚙️ Common definitions, error codes, macros, and types shared throughout the application
asciichat_error_t connection_endpoint_resolve(const char *input, uint16_t default_port, connection_endpoint_t *endpoint_out)
@ CONNECTION_ENDPOINT_TCP
@ CONNECTION_ENDPOINT_WEBSOCKET
asciichat_error_t connection_factory_open(const char *name, const char *input, uint16_t default_port, crypto_context_t *crypto_ctx, acip_transport_t **transport_out, connection_endpoint_t *endpoint_out)
Shared connection factory for TCP and WebSocket endpoints.
unsigned short uint16_t
Definition common.h:57
#define SET_ERRNO(code, context_msg,...)
Set error code with custom context message and log it, returning the error code.
asciichat_error_t
Error and exit codes - unified status values (0-255)
Definition error_codes.h:49
@ ERROR_NETWORK_CONNECT
Definition error_codes.h:79
@ ERROR_NETWORK
Definition error_codes.h:77
@ ASCIICHAT_OK
Definition error_codes.h:51
@ ERROR_INVALID_PARAM
#define log_error(...)
Log an ERROR message.
Definition log/log.h:587
#define CONNECT_TIMEOUT
Connection timeout in seconds (3 seconds)
bool connect_with_timeout(socket_t sockfd, const struct sockaddr *addr, socklen_t addrlen, int timeout_seconds)
Connect with timeout.
int safe_snprintf(char *buffer, size_t buffer_size, const char *format,...)
Safe formatted string printing to buffer.
Definition system.c:148
#define INVALID_SOCKET_VALUE
Invalid socket value (POSIX: -1)
Definition socket.h:278
int socket_close(socket_t sock)
Close a socket.
int socket_t
📝 Logging API with multiple log levels and terminal output control
🌐 Core network I/O operations with timeout support
Transport instance structure.
Definition transport.h:214
connection_endpoint_protocol_t protocol
Cryptographic context structure.
acip_transport_t * acip_tcp_transport_create(const char *name, socket_t sockfd, crypto_context_t *crypto_ctx)
Create TCP transport from existing socket.
acip_transport_t * acip_websocket_client_transport_create(const char *name, const char *url, crypto_context_t *crypto_ctx)
Create WebSocket client transport.