mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-12-04 14:46:30 -05:00
Merge branch 'feature-ping' into devel
This commit is contained in:
commit
28b4ff2d55
@ -45,6 +45,7 @@ noinst_HEADERS = \
|
||||
fastevent.h \
|
||||
navigation.h \
|
||||
event.h \
|
||||
ping.h \
|
||||
acl.h auth.h \
|
||||
metadata_xiph.h \
|
||||
format.h \
|
||||
@ -121,6 +122,7 @@ icecast_SOURCES = \
|
||||
if HAVE_CURL
|
||||
icecast_SOURCES += \
|
||||
curl.c \
|
||||
ping.c \
|
||||
auth_url.c \
|
||||
event_url.c
|
||||
endif
|
||||
@ -143,6 +145,7 @@ endif
|
||||
|
||||
EXTRA_icecast_SOURCES = \
|
||||
curl.c \
|
||||
ping.c \
|
||||
yp.c \
|
||||
auth_url.c \
|
||||
event_url.c \
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
#include "global.h" /* for igloo_instance */
|
||||
#include "string_renderer.h"
|
||||
#include "curl.h"
|
||||
#include "ping.h"
|
||||
#include "event.h"
|
||||
#include "cfgfile.h"
|
||||
#include "util.h"
|
||||
@ -31,23 +31,10 @@ typedef struct event_url {
|
||||
bool legacy;
|
||||
char *url;
|
||||
char *action;
|
||||
char *userpwd;
|
||||
CURL *handle;
|
||||
char errormsg[CURL_ERROR_SIZE];
|
||||
char *username;
|
||||
char *password;
|
||||
} event_url_t;
|
||||
|
||||
static size_t handle_returned (void *ptr, size_t size, size_t nmemb, void *stream) {
|
||||
(void)ptr, (void)stream;
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
static inline char *__escape(const char *src, const char *default_value) {
|
||||
if (src)
|
||||
return util_url_escape(src);
|
||||
|
||||
return strdup(default_value);
|
||||
}
|
||||
|
||||
static int event_url_emit(void *state, event_t *event) {
|
||||
event_url_t *self = state;
|
||||
ice_config_t *config;
|
||||
@ -92,18 +79,7 @@ static int event_url_emit(void *state, event_t *event) {
|
||||
|
||||
string_renderer_end_list(renderer);
|
||||
|
||||
|
||||
if (strchr(self->url, '@') == NULL && self->userpwd) {
|
||||
curl_easy_setopt(self->handle, CURLOPT_USERPWD, self->userpwd);
|
||||
} else {
|
||||
curl_easy_setopt(self->handle, CURLOPT_USERPWD, "");
|
||||
}
|
||||
|
||||
curl_easy_setopt(self->handle, CURLOPT_URL, self->url);
|
||||
curl_easy_setopt(self->handle, CURLOPT_POSTFIELDS, string_renderer_to_string_zero_copy(renderer));
|
||||
|
||||
if (curl_easy_perform(self->handle))
|
||||
ICECAST_LOG_WARN("auth to server %s failed with %s", self->url, self->errormsg);
|
||||
ping_simple(self->url, self->username, self->password, string_renderer_to_string_zero_copy(renderer));
|
||||
|
||||
igloo_ro_unref(&renderer);
|
||||
|
||||
@ -112,17 +88,15 @@ static int event_url_emit(void *state, event_t *event) {
|
||||
|
||||
static void event_url_free(void *state) {
|
||||
event_url_t *self = state;
|
||||
icecast_curl_free(self->handle);
|
||||
free(self->url);
|
||||
free(self->action);
|
||||
free(self->userpwd);
|
||||
free(self->username);
|
||||
free(self->password);
|
||||
free(self);
|
||||
}
|
||||
|
||||
int event_get_url(event_registration_t *er, config_options_t *options) {
|
||||
event_url_t *self = calloc(1, sizeof(event_url_t));
|
||||
const char *username = NULL;
|
||||
const char *password = NULL;
|
||||
|
||||
if (!self)
|
||||
return -1;
|
||||
@ -144,9 +118,9 @@ int event_get_url(event_registration_t *er, config_options_t *options) {
|
||||
if (strcmp(options->name, "url") == 0) {
|
||||
util_replace_string(&(self->url), options->value);
|
||||
} else if (strcmp(options->name, "username") == 0) {
|
||||
username = options->value;
|
||||
util_replace_string(&(self->username), options->value);
|
||||
} else if (strcmp(options->name, "password") == 0) {
|
||||
password = options->value;
|
||||
util_replace_string(&(self->password), options->value);
|
||||
} else if (strcmp(options->name, "action") == 0) {
|
||||
util_replace_string(&(self->action), options->value);
|
||||
} else if (strcmp(options->name, "legacy") == 0) {
|
||||
@ -157,27 +131,12 @@ int event_get_url(event_registration_t *er, config_options_t *options) {
|
||||
} while ((options = options->next));
|
||||
}
|
||||
|
||||
self->handle = icecast_curl_new(NULL, NULL);
|
||||
|
||||
/* check if we are in sane state */
|
||||
if (!self->url || !self->handle) {
|
||||
if (!self->url) {
|
||||
event_url_free(self);
|
||||
return -1;
|
||||
}
|
||||
|
||||
curl_easy_setopt(self->handle, CURLOPT_HEADERFUNCTION, handle_returned);
|
||||
curl_easy_setopt(self->handle, CURLOPT_ERRORBUFFER, self->errormsg);
|
||||
|
||||
if (username && password) {
|
||||
size_t len = strlen(username) + strlen(password) + 2;
|
||||
self->userpwd = malloc(len);
|
||||
if (!self->userpwd) {
|
||||
event_url_free(self);
|
||||
return -1;
|
||||
}
|
||||
snprintf(self->userpwd, len, "%s:%s", username, password);
|
||||
}
|
||||
|
||||
er->state = self;
|
||||
er->emit = event_url_emit;
|
||||
er->free = event_url_free;
|
||||
|
@ -82,6 +82,7 @@
|
||||
#include "yp.h"
|
||||
#include "auth.h"
|
||||
#include "event.h"
|
||||
#include "ping.h"
|
||||
#include "listensocket.h"
|
||||
#include "fastevent.h"
|
||||
#include "prng.h"
|
||||
@ -169,6 +170,7 @@ static void initialize_subsystems(void)
|
||||
xslt_initialize();
|
||||
#ifdef HAVE_CURL
|
||||
icecast_curl_initialize();
|
||||
ping_initialize();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -182,6 +184,9 @@ static void shutdown_subsystems(void)
|
||||
auth_shutdown();
|
||||
yp_shutdown();
|
||||
stats_shutdown();
|
||||
#ifdef HAVE_CURL
|
||||
ping_shutdown();
|
||||
#endif
|
||||
|
||||
ICECAST_LOG_DEBUG("Shuting down connection related subsystems...");
|
||||
connection_shutdown();
|
||||
|
161
src/ping.c
Normal file
161
src/ping.c
Normal file
@ -0,0 +1,161 @@
|
||||
/* Icecast
|
||||
*
|
||||
* Copyright 2023 Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>
|
||||
*
|
||||
* This program is distributed under the GNU General Public License, version 2.
|
||||
* A copy of this license is included with this source.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "thread/thread.h"
|
||||
|
||||
#include "ping.h"
|
||||
#include "logging.h"
|
||||
#include "curl.h"
|
||||
|
||||
#define CATMODULE "ping"
|
||||
|
||||
typedef struct ping_queue_tag ping_queue_t;
|
||||
|
||||
struct ping_queue_tag {
|
||||
CURL *curl;
|
||||
ping_queue_t *next;
|
||||
};
|
||||
|
||||
static bool ping_running = false;
|
||||
static thread_type *ping_thread_id;
|
||||
static mutex_t ping_mutex;
|
||||
static ping_queue_t *ping_queue;
|
||||
static cond_t ping_cond;
|
||||
|
||||
static void on_done(ping_queue_t *entry)
|
||||
{
|
||||
icecast_curl_free(entry->curl);
|
||||
free(entry);
|
||||
}
|
||||
|
||||
static void *ping_thread(void *arg)
|
||||
{
|
||||
CURLM *curl_multi = curl_multi_init();
|
||||
|
||||
while (ping_running) {
|
||||
ping_queue_t *take;
|
||||
int status;
|
||||
|
||||
thread_mutex_lock(&ping_mutex);
|
||||
take = ping_queue;
|
||||
ping_queue = NULL;
|
||||
thread_mutex_unlock(&ping_mutex);
|
||||
|
||||
while (take) {
|
||||
ping_queue_t *entry = take;
|
||||
|
||||
take = take->next;
|
||||
entry->next = NULL;
|
||||
|
||||
curl_easy_setopt(entry->curl, CURLOPT_PRIVATE, entry);
|
||||
curl_multi_add_handle(curl_multi, entry->curl);
|
||||
}
|
||||
|
||||
if (curl_multi_perform(curl_multi, &status) != CURLM_OK)
|
||||
break;
|
||||
|
||||
if (!status) {
|
||||
if (!ping_running)
|
||||
break;
|
||||
thread_cond_wait(&ping_cond);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (curl_multi_wait(curl_multi, NULL, 0, 1000, &status) != CURLM_OK)
|
||||
break;
|
||||
|
||||
while (true) {
|
||||
struct CURLMsg *m = curl_multi_info_read(curl_multi, &status);
|
||||
|
||||
if (!m)
|
||||
break;
|
||||
|
||||
if (m->msg == CURLMSG_DONE) {
|
||||
ping_queue_t *entry = NULL;
|
||||
CURL *e = m->easy_handle;
|
||||
curl_multi_remove_handle(curl_multi, e);
|
||||
curl_easy_getinfo(e, CURLINFO_PRIVATE, &entry);
|
||||
on_done(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
curl_multi_cleanup(curl_multi);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void ping_add_to_queue(ping_queue_t *entry)
|
||||
{
|
||||
thread_mutex_lock(&ping_mutex);
|
||||
entry->next = ping_queue;
|
||||
ping_queue = entry;
|
||||
thread_mutex_unlock(&ping_mutex);
|
||||
thread_cond_broadcast(&ping_cond);
|
||||
}
|
||||
|
||||
void ping_simple(const char *url, const char *username, const char *password, const char *data)
|
||||
{
|
||||
ping_queue_t *entry = calloc(1, sizeof(*entry));
|
||||
|
||||
if (!entry)
|
||||
return;
|
||||
|
||||
entry->curl = icecast_curl_new(url, NULL);
|
||||
if (!entry->curl) {
|
||||
free(entry);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strchr(url, '@') == NULL) {
|
||||
if (username)
|
||||
curl_easy_setopt(entry->curl, CURLOPT_USERNAME, username);
|
||||
if (password)
|
||||
curl_easy_setopt(entry->curl, CURLOPT_PASSWORD, password);
|
||||
}
|
||||
|
||||
if (data)
|
||||
curl_easy_setopt(entry->curl, CURLOPT_COPYPOSTFIELDS, data);
|
||||
|
||||
ping_add_to_queue(entry);
|
||||
}
|
||||
|
||||
void ping_initialize(void)
|
||||
{
|
||||
if (ping_running)
|
||||
return;
|
||||
|
||||
thread_mutex_create(&ping_mutex);
|
||||
thread_cond_create(&ping_cond);
|
||||
|
||||
ping_running = true;
|
||||
ping_thread_id = thread_create("Ping Thread", ping_thread, NULL, THREAD_ATTACHED);
|
||||
}
|
||||
|
||||
void ping_shutdown(void)
|
||||
{
|
||||
if (!ping_running)
|
||||
return;
|
||||
|
||||
ping_running = false;
|
||||
ICECAST_LOG_DEBUG("Waiting for ping thread");
|
||||
thread_cond_broadcast(&ping_cond);
|
||||
thread_join(ping_thread_id);
|
||||
thread_mutex_destroy(&ping_mutex);
|
||||
thread_cond_destroy(&ping_cond);
|
||||
ICECAST_LOG_DEBUG("Joined ping thread, good job!");
|
||||
}
|
17
src/ping.h
Normal file
17
src/ping.h
Normal file
@ -0,0 +1,17 @@
|
||||
/* Icecast
|
||||
*
|
||||
* Copyright 2023 Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>
|
||||
*
|
||||
* This program is distributed under the GNU General Public License, version 2.
|
||||
* A copy of this license is included with this source.
|
||||
*/
|
||||
|
||||
#ifndef __PING_H__
|
||||
#define __PING_H__
|
||||
|
||||
void ping_initialize(void);
|
||||
void ping_shutdown(void);
|
||||
|
||||
void ping_simple(const char *url, const char *username, const char *password, const char *data);
|
||||
|
||||
#endif /* __PING_H__ */
|
Loading…
Reference in New Issue
Block a user