Mercurial
comparison seobeo/s_network.c @ 231:09a96dcb2b4c hg-web
[merge] Join existing hg-web branch head
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Sun, 02 Aug 2026 16:50:48 -0700 |
| parents | 0e7b9464248d |
| children | b8aa08503378 |
comparison
equal
deleted
inserted
replaced
| 217:7ef4c9d2a72d | 231:09a96dcb2b4c |
|---|---|
| 1 #include "seobeo/seobeo.h" | 1 #include "seobeo/seobeo.h" |
| 2 | 2 |
| 3 static pthread_once_t g_sigpipe_once = PTHREAD_ONCE_INIT; | |
| 4 | |
| 5 static void Seobeo_Process_Ignore_Sigpipe(void) | |
| 6 { | |
| 7 signal(SIGPIPE, SIG_IGN); | |
| 8 } | |
| 9 | |
| 10 static void Seobeo_Socket_Disable_Sigpipe(int socket_fd) | |
| 11 { | |
| 12 #ifdef SO_NOSIGPIPE | |
| 13 int enabled = 1; | |
| 14 setsockopt(socket_fd, SOL_SOCKET, SO_NOSIGPIPE, &enabled, sizeof(enabled)); | |
| 15 #else | |
| 16 (void)socket_fd; | |
| 17 #endif | |
| 18 } | |
| 19 | |
| 20 static ssize_t Seobeo_Socket_Write( | |
| 21 int socket_fd, | |
| 22 const void *buffer, | |
| 23 size_t length) | |
| 24 { | |
| 25 #ifdef MSG_NOSIGNAL | |
| 26 return send(socket_fd, buffer, length, MSG_NOSIGNAL); | |
| 27 #else | |
| 28 return send(socket_fd, buffer, length, 0); | |
| 29 #endif | |
| 30 } | |
| 3 | 31 |
| 4 Seobeo_Handle *Seobeo_Stream_Handle_Server_Create(const char *host, const char* port) | 32 Seobeo_Handle *Seobeo_Stream_Handle_Server_Create(const char *host, const char* port) |
| 5 { | 33 { |
| 34 pthread_once(&g_sigpipe_once, Seobeo_Process_Ignore_Sigpipe); | |
| 6 Seobeo_Handle *p_handle; | 35 Seobeo_Handle *p_handle; |
| 7 struct addrinfo hints, *server_infos, *free_server_info; | 36 struct addrinfo hints, *server_infos, *free_server_info; |
| 8 int32 socket_fd, yes = 1; // Need this for setsockopt | 37 int32 socket_fd, yes = 1; // Need this for setsockopt |
| 9 | 38 |
| 10 memset(&hints, 0, sizeof hints); | 39 memset(&hints, 0, sizeof hints); |
| 24 ) | 53 ) |
| 25 { | 54 { |
| 26 if((socket_fd = socket(free_server_info->ai_family, | 55 if((socket_fd = socket(free_server_info->ai_family, |
| 27 free_server_info->ai_socktype, free_server_info->ai_protocol)) == -1) | 56 free_server_info->ai_socktype, free_server_info->ai_protocol)) == -1) |
| 28 { perror("socket"); continue; } | 57 { perror("socket"); continue; } |
| 58 Seobeo_Socket_Disable_Sigpipe(socket_fd); | |
| 29 | 59 |
| 30 if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) | 60 if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) |
| 31 { perror("setsockopt SO_REUSEADDR"); continue; } | 61 { perror("setsockopt SO_REUSEADDR"); continue; } |
| 32 | 62 |
| 33 #ifdef SO_REUSEPORT | 63 #ifdef SO_REUSEPORT |
| 79 } | 109 } |
| 80 | 110 |
| 81 | 111 |
| 82 Seobeo_Handle *Seobeo_Stream_Handle_Client_Create(const char *host, const char* port, boolean use_tls) | 112 Seobeo_Handle *Seobeo_Stream_Handle_Client_Create(const char *host, const char* port, boolean use_tls) |
| 83 { | 113 { |
| 114 pthread_once(&g_sigpipe_once, Seobeo_Process_Ignore_Sigpipe); | |
| 84 Seobeo_Handle *p_handle; | 115 Seobeo_Handle *p_handle; |
| 85 p_handle = malloc(sizeof(*p_handle)); | 116 p_handle = malloc(sizeof(*p_handle)); |
| 86 | 117 |
| 87 struct addrinfo hints, *server_infos; | 118 struct addrinfo hints, *server_infos; |
| 88 int32 socket_fd; // Need this for setsockopt | 119 int32 socket_fd; // Need this for setsockopt |
| 96 | 127 |
| 97 | 128 |
| 98 if((socket_fd = socket(server_infos->ai_family, | 129 if((socket_fd = socket(server_infos->ai_family, |
| 99 server_infos->ai_socktype, server_infos->ai_protocol)) == -1) | 130 server_infos->ai_socktype, server_infos->ai_protocol)) == -1) |
| 100 { perror("socket"); return NULL; } | 131 { perror("socket"); return NULL; } |
| 132 Seobeo_Socket_Disable_Sigpipe(socket_fd); | |
| 101 | 133 |
| 102 if (connect(socket_fd, server_infos->ai_addr, server_infos->ai_addrlen) != 0) | 134 if (connect(socket_fd, server_infos->ai_addr, server_infos->ai_addrlen) != 0) |
| 103 { perror("connect"); return NULL; } | 135 { perror("connect"); return NULL; } |
| 104 freeaddrinfo(server_infos); | 136 freeaddrinfo(server_infos); |
| 105 | 137 |
| 152 inet_ntop( | 184 inet_ntop( |
| 153 addr.ss_family, | 185 addr.ss_family, |
| 154 Seobeo_Get_IP4_Or_IP6((struct sockaddr *)&addr), | 186 Seobeo_Get_IP4_Or_IP6((struct sockaddr *)&addr), |
| 155 client_inet_addr, sizeof client_inet_addr); | 187 client_inet_addr, sizeof client_inet_addr); |
| 156 if (client_fd == -1) return NULL; | 188 if (client_fd == -1) return NULL; |
| 189 Seobeo_Socket_Disable_Sigpipe(client_fd); | |
| 157 | 190 |
| 158 // Set non blocking... | 191 // Set non blocking... |
| 159 int flags = fcntl(client_fd, F_GETFL, 0); | 192 int flags = fcntl(client_fd, F_GETFL, 0); |
| 160 if (flags == -1) return NULL; | 193 if (flags == -1) return NULL; |
| 161 fcntl(client_fd, F_SETFL, flags | O_NONBLOCK); | 194 fcntl(client_fd, F_SETFL, flags | O_NONBLOCK); |
| 234 if (n == 0) return 0; // would block | 267 if (n == 0) return 0; // would block |
| 235 sent += (uint32)n; | 268 sent += (uint32)n; |
| 236 }else | 269 }else |
| 237 { | 270 { |
| 238 Seobeo_Log(SEOBEO_DEBUG, "Flushing socket: %d\n", p_handle->socket); | 271 Seobeo_Log(SEOBEO_DEBUG, "Flushing socket: %d\n", p_handle->socket); |
| 239 ssize_t n = write( | 272 ssize_t n = Seobeo_Socket_Write( |
| 240 p_handle->socket, | 273 p_handle->socket, |
| 241 p_handle->write_buffer + sent, | 274 p_handle->write_buffer + sent, |
| 242 total - sent | 275 total - sent |
| 243 ); | 276 ); |
| 244 if (n < 0) { | 277 if (n < 0) { |
| 266 if (data_size > p_handle->write_buffer_capacity) | 299 if (data_size > p_handle->write_buffer_capacity) |
| 267 { | 300 { |
| 268 uint32 offset = 0; | 301 uint32 offset = 0; |
| 269 while (offset < data_size) | 302 while (offset < data_size) |
| 270 { | 303 { |
| 271 ssize_t n = write(p_handle->socket, | 304 ssize_t n; |
| 272 data + offset, | 305 if (p_handle->ssl) |
| 273 data_size - offset); | 306 { |
| 307 n = Seobeo_SSL_Write(p_handle, data + offset, data_size - offset); | |
| 308 } | |
| 309 else | |
| 310 { | |
| 311 n = Seobeo_Socket_Write( | |
| 312 p_handle->socket, | |
| 313 data + offset, | |
| 314 data_size - offset); | |
| 315 } | |
| 316 | |
| 274 if (n==0) | 317 if (n==0) |
| 275 { | 318 { |
| 276 // DEBUG | 319 // DEBUG |
| 277 Seobeo_Log(SEOBEO_DEBUG, "Write offset: %d\n", offset); | 320 Seobeo_Log(SEOBEO_DEBUG, "Write offset: %d\n", offset); |
| 278 break; | 321 break; |