ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode ssl_mode, struct ssl_context_handle* ssl_ctx) { uhub_assert(con); uhub_assert(ssl_ctx); struct net_context_openssl* ctx = (struct net_context_openssl*) ssl_ctx; struct net_ssl_openssl* handle = (struct net_ssl_openssl*) hub_malloc_zero(sizeof(struct net_ssl_openssl)); if (ssl_mode == net_con_ssl_mode_server) { handle->ssl = SSL_new(ctx->ssl); if (!handle->ssl) { LOG_ERROR("Unable to create new SSL stream\n"); return -1; } SSL_set_fd(handle->ssl, con->sd); handle->bio = SSL_get_rbio(handle->ssl); con->ssl = (struct ssl_handle*) handle; return net_con_ssl_accept(con); } else { handle->ssl = SSL_new(ctx->ssl); SSL_set_fd(handle->ssl, con->sd); handle->bio = SSL_get_rbio(handle->ssl); con->ssl = (struct ssl_handle*) handle; return net_con_ssl_connect(con); } }
int command_del(struct command_base* cbase, struct command_handle* cmd) { uhub_assert(cbase != NULL); uhub_assert(cmd != NULL); list_remove(cbase->handlers, cmd); return 1; }
int command_add(struct command_base* cbase, struct command_handle* cmd, void* ptr) { uhub_assert(cbase != NULL); uhub_assert(cmd != NULL); uhub_assert(cmd->length == strlen(cmd->prefix)); uhub_assert(cmd->handler != NULL); uhub_assert(cmd->description && *cmd->description); list_append(cbase->handlers, cmd); cbase->prefix_length_max = MAX(cmd->length, cbase->prefix_length_max); cmd->ptr = ptr; return 1; }
static void timeout_queue_remove_locked(struct timeout_queue* t, struct timeout_evt* evt) { uhub_assert(evt->prev == &t->lock); if (t->lock.next == evt) { t->lock.next = evt->next; if (t->lock.prev == evt) t->lock.prev = evt->next; } else { struct timeout_evt *prev, *it; prev = 0; it = t->lock.next; while (it) { prev = it; it = it->next; if (it == evt) { prev->next = it->next; if (!prev->next) t->lock.prev = prev; } } } timeout_evt_reset(evt); }
struct plugin_hub_internals* get_internals(struct plugin_handle* handle) { struct plugin_hub_internals* internals; uhub_assert(handle && handle->handle && handle->handle->internals); internals = (struct plugin_hub_internals*) handle->handle->internals; return internals; }
struct command_base* command_initialize(struct hub_info* hub) { struct command_base* cbase = (struct command_base*) hub_malloc(sizeof(struct command_base)); uhub_assert(cbase != NULL); // uhub_assert(hub != NULL); cbase->hub = hub; cbase->handlers = (struct linked_list*) list_create(); cbase->prefix_length_max = 0; uhub_assert(cbase->handlers != NULL); commands_builtin_add(cbase); return cbase; }
int route_to_user(struct hub_info* hub, struct hub_user* user, struct adc_message* msg) { #ifdef DEBUG_SENDQ char* data = strndup(msg->cache, msg->length-1); LOG_PROTO("send %s: \"%s\"", sid_to_string(user->id.sid), data); free(data); #endif if (!user->connection) return 0; uhub_assert(msg->cache && *msg->cache); if (ioq_send_is_empty(user->send_queue) && !user_flag_get(user, flag_pipeline)) { /* Perform oportunistic write */ ioq_send_add(user->send_queue, msg); handle_net_write(user); } else { if (check_send_queue(hub, user, msg) >= 0) { ioq_send_add(user->send_queue, msg); if (!user_flag_get(user, flag_pipeline)) user_net_io_want_write(user); } } return 1; }
void command_shutdown(struct command_base* cbase) { commands_builtin_remove(cbase); uhub_assert(list_size(cbase->handlers) == 0); list_destroy(cbase->handlers); hub_free(cbase); }
void timeout_queue_insert(struct timeout_queue* t, struct timeout_evt* evt, size_t seconds) { struct timeout_evt* first; size_t pos = ((t->last + seconds) % t->max); evt->timestamp = t->last + seconds; evt->next = 0; if (timeout_queue_locked(t)) { timeout_queue_insert_locked(t, evt); return; } first = t->events[pos]; if (first) { uhub_assert(first->timestamp == evt->timestamp); first->prev->next = evt; evt->prev = first->prev; first->prev = evt; } else { t->events[pos] = evt; evt->prev = evt; } evt->next = 0; }
void cbuf_append_strftime(struct cbuffer* buf, const char* format, const struct tm* tm) { static char tmp[MAX_MSG_LEN]; int bytes; uhub_assert(buf->flags == 0); bytes = strftime(tmp, sizeof(tmp), format, tm); cbuf_append_bytes(buf, tmp, bytes); }
static struct log_data* parse_config(const char* line, struct plugin_handle* plugin) { struct log_data* data = (struct log_data*) hub_malloc_zero(sizeof(struct log_data)); struct cfg_tokens* tokens = cfg_tokenize(line); char* token = cfg_token_get_first(tokens); uhub_assert(data != NULL); data->srvtdiff = 0; while (token) { struct cfg_settings* setting = cfg_settings_split(token); if (!setting) { set_error_message(plugin, "Unable to parse startup parameters"); cfg_tokens_free(tokens); hub_free(data); return 0; } if (strcmp(cfg_settings_get_key(setting), "file") == 0) { if (!data->db) { if (sqlite3_open(cfg_settings_get_value(setting), &data->db)) { cfg_tokens_free(tokens); cfg_settings_free(setting); hub_free(data); set_error_message(plugin, "Unable to open database file"); return 0; } } } else if (strcmp(cfg_settings_get_key(setting), "server_time_diff") == 0) { data->srvtdiff = uhub_atoi(cfg_settings_get_value(setting)); } else { set_error_message(plugin, "Unknown startup parameters given"); cfg_tokens_free(tokens); cfg_settings_free(setting); hub_free(data); return 0; } cfg_settings_free(setting); token = cfg_token_get_next(tokens); } cfg_tokens_free(tokens); return data; }
void cbuf_append_bytes(struct cbuffer* buf, const char* msg, size_t len) { uhub_assert(buf->flags == 0); if (buf->size + len >= buf->capacity) cbuf_resize(buf, buf->size + len); memcpy(buf->buf + buf->size, msg, len); buf->size += len; buf->buf[buf->size] = '\0'; }
void cbuf_append_format(struct cbuffer* buf, const char* format, ...) { static char tmp[MAX_MSG_LEN]; va_list args; int bytes; uhub_assert(buf->flags == 0); va_start(args, format); bytes = vsnprintf(tmp, sizeof(tmp), format, args); va_end(args); cbuf_append_bytes(buf, tmp, bytes); }
void ADC_client_send(struct ADC_client* client, struct adc_message* msg) { ADC_TRACE; uhub_assert(client->con != NULL); uhub_assert(msg->cache && *msg->cache); if (ioq_send_is_empty(client->send_queue) && !(client->flags & cflag_pipe)) { /* Perform oportunistic write */ ioq_send_add(client->send_queue, msg); ADC_client_send_queue(client); } else { ioq_send_add(client->send_queue, msg); if (!(client->flags & cflag_pipe)) net_con_update(client->con, NET_EVENT_READ | NET_EVENT_WRITE); } }
static void net_connect_callback(struct net_connect_handle* handle, enum net_connect_status status, struct net_connection* con) { uhub_assert(handle->callback != NULL); // Call the callback handle->callback(handle, status, con, handle->ptr); handle->callback = NULL; // Cleanup net_connect_destroy(handle); }
static struct chat_history_data* parse_config(const char* line, struct plugin_handle* plugin) { struct chat_history_data* data = (struct chat_history_data*) hub_malloc_zero(sizeof(struct chat_history_data)); struct cfg_tokens* tokens = cfg_tokenize(line); char* token = cfg_token_get_first(tokens); uhub_assert(data != NULL); data->history_max = 200; data->history_default = 25; data->history_connect = 5; data->chat_history = list_create(); while (token) { struct cfg_settings* setting = cfg_settings_split(token); if (!setting) { set_error_message(plugin, "Unable to parse startup parameters"); cfg_tokens_free(tokens); hub_free(data); return 0; } if (strcmp(cfg_settings_get_key(setting), "history_max") == 0) { data->history_max = (size_t) uhub_atoi(cfg_settings_get_value(setting)); } else if (strcmp(cfg_settings_get_key(setting), "history_default") == 0) { data->history_default = (size_t) uhub_atoi(cfg_settings_get_value(setting)); } else if (strcmp(cfg_settings_get_key(setting), "history_connect") == 0) { data->history_connect = (size_t) uhub_atoi(cfg_settings_get_value(setting)); } else { set_error_message(plugin, "Unknown startup parameters given"); cfg_tokens_free(tokens); cfg_settings_free(setting); hub_free(data); return 0; } cfg_settings_free(setting); token = cfg_token_get_next(tokens); } cfg_tokens_free(tokens); return data; }
/* NOTE: msg must be unterminated here */ static int adc_msg_cache_append(struct adc_message* msg, const char* string, size_t len) { if (!adc_msg_grow(msg, msg->length + len)) { /* FIXME: OOM! */ return 0; } memcpy(&msg->cache[msg->length], string, len); adc_msg_set_length(msg, msg->length + len); uhub_assert(msg->capacity > msg->length); msg->cache[msg->length] = 0; return 1; }
ssize_t net_ssl_send(struct net_connection* con, const void* buf, size_t len) { struct net_ssl_openssl* handle = get_handle(con); uhub_assert(handle->state == tls_st_connected); ERR_clear_error(); ssize_t ret = SSL_write(handle->ssl, buf, len); add_io_stats(handle); LOG_PROTO("SSL_write(con=%p, buf=%p, len=" PRINTF_SIZE_T ") => %d", con, buf, len, ret); if (ret > 0) handle->ssl_write_events = 0; else ret = handle_openssl_error(con, ret, 0); net_ssl_update(con, handle->events); // Update backend only return ret; }
int event_queue_process(struct event_queue* queue) { struct event_data* data; if (queue->locked) return 0; /* lock primary queue, and handle the primary queue messages. */ queue->locked = 1; data = (struct event_data*) list_get_first(queue->q1); while (data) { #ifdef EQ_DEBUG eq_debug("EXEC", data); #endif queue->callback(queue->callback_data, data); data = (struct event_data*) list_get_next(queue->q1); } list_clear(queue->q1, event_queue_cleanup_callback); uhub_assert(list_size(queue->q1) == 0); /* unlock queue */ queue->locked = 0; /* transfer from secondary queue to the primary queue. */ data = (struct event_data*) list_get_first(queue->q2); while (data) { list_remove(queue->q2, data); list_append(queue->q1, data); data = (struct event_data*) list_get_first(queue->q2); } /* if more events exist, schedule it */ if (list_size(queue->q1)) { return 1; } return 0; }
static struct net_ssl_openssl* get_handle(struct net_connection* con) { uhub_assert(con); return (struct net_ssl_openssl*) con->ssl; }
static void hub_event_dispatcher(void* callback_data, struct event_data* message) { int status; struct hub_info* hub = (struct hub_info*) callback_data; struct hub_user* user = (struct hub_user*) message->ptr; uhub_assert(hub != NULL); switch (message->id) { case UHUB_EVENT_USER_JOIN: { if (user_is_disconnecting(user)) break; if (message->flags) { hub_send_password_challenge(hub, user); } else { /* Race condition, we could have two messages for two logins queued up. So make sure we don't let the second client in. */ status = check_duplicate_logins_ok(hub, user); if (!status) { on_login_success(hub, user); } else { on_login_failure(hub, user, (enum status_message) status); } } break; } case UHUB_EVENT_USER_QUIT: { uman_remove(hub->users, user); uman_send_quit_message(hub, hub->users, user); on_logout_user(hub, user); hub_schedule_destroy_user(hub, user); break; } case UHUB_EVENT_USER_DESTROY: { user_destroy(user); break; } case UHUB_EVENT_HUB_SHUTDOWN: { struct hub_user* u = (struct hub_user*) list_get_first(hub->users->list); while (u) { uman_remove(hub->users, u); user_destroy(u); u = (struct hub_user*) list_get_first(hub->users->list); } break; } default: /* FIXME: ignored */ break; } }
void cbuf_append(struct cbuffer* buf, const char* msg) { size_t len = strlen(msg); uhub_assert(buf->flags == 0); cbuf_append_bytes(buf, msg, len); }
int command_is_available(struct command_handle* handle, enum auth_credentials credentials) { uhub_assert(handle != NULL); return handle->cred <= credentials; }
void cbuf_resize(struct cbuffer* buf, size_t capacity) { uhub_assert(buf->flags == 0); buf->capacity = capacity; buf->buf = hub_realloc(buf->buf, capacity + 1); }