| 238 | } |
| 239 | |
| 240 | int websocket_create(const NETADDR *bindaddr) |
| 241 | { |
| 242 | // find free context |
| 243 | int first_free = -1; |
| 244 | for(int i = 0; i < (int)std::size(contexts); i++) |
| 245 | { |
| 246 | if(contexts[i].context == nullptr) |
| 247 | { |
| 248 | first_free = i; |
| 249 | break; |
| 250 | } |
| 251 | } |
| 252 | if(first_free == -1) |
| 253 | { |
| 254 | log_error("websockets", "Failed to create websocket: no free contexts available"); |
| 255 | return -1; |
| 256 | } |
| 257 | |
| 258 | context_data *ctx_data = &contexts[first_free]; |
| 259 | mem_zero(&ctx_data->creation_info, sizeof(ctx_data->creation_info)); |
| 260 | ctx_data->creation_info.options = LWS_SERVER_OPTION_FAIL_UPON_UNABLE_TO_BIND; |
| 261 | if(bindaddr->type == NETTYPE_WEBSOCKET_IPV6) |
| 262 | { |
| 263 | // Set IPv6-only mode and socket option for IPv6 Websockets. |
| 264 | ctx_data->creation_info.options |= LWS_SERVER_OPTION_IPV6_V6ONLY_VALUE | LWS_SERVER_OPTION_IPV6_V6ONLY_MODIFY; |
| 265 | } |
| 266 | net_addr_str(bindaddr, ctx_data->bindaddr_str, sizeof(ctx_data->bindaddr_str), false); |
| 267 | if(ctx_data->bindaddr_str[0] == '[' && ctx_data->bindaddr_str[str_length(ctx_data->bindaddr_str) - 1] == ']') |
| 268 | { |
| 269 | // Bindaddr must not be enclosed in brackets for IPv6 Websockets. |
| 270 | ctx_data->bindaddr_str[str_length(ctx_data->bindaddr_str) - 1] = '\0'; |
| 271 | mem_move(&ctx_data->bindaddr_str[0], &ctx_data->bindaddr_str[1], str_length(ctx_data->bindaddr_str) + 1); |
| 272 | } |
| 273 | ctx_data->creation_info.iface = ctx_data->bindaddr_str; |
| 274 | ctx_data->creation_info.port = bindaddr->port; |
| 275 | ctx_data->creation_info.protocols = protocols; |
| 276 | ctx_data->creation_info.gid = -1; |
| 277 | ctx_data->creation_info.uid = -1; |
| 278 | ctx_data->creation_info.user = ctx_data; |
| 279 | |
| 280 | ctx_data->context = lws_create_context(&ctx_data->creation_info); |
| 281 | if(ctx_data->context == nullptr) |
| 282 | { |
| 283 | return -1; |
| 284 | } |
| 285 | contexts_map[ctx_data->context] = ctx_data; |
| 286 | ctx_data->recv_buffer.Init(); |
| 287 | return first_free; |
| 288 | } |
| 289 | |
| 290 | void websocket_destroy(int socket) |
| 291 | { |
no test coverage detected