mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2025-02-02 15:07:36 -05:00
Feature: Allow listen sockets to virtually handle other sockets traffic.
This adds on-behalf-of="#id" to <listen-socket>. It allows a socket to handle the traffic that was originally meant of another (virtual) listen socket.
This commit is contained in:
parent
7742bf0a21
commit
80ffdca7d1
@ -186,6 +186,19 @@ static listener_type_t config_str_to_listener_type(const char *str)
|
||||
}
|
||||
}
|
||||
|
||||
char * config_href_to_id(const char *href)
|
||||
{
|
||||
if (!href || !*href)
|
||||
return NULL;
|
||||
|
||||
if (*href != '#') {
|
||||
ICECAST_LOG_ERROR("Can not convert string \"%H\" to ID.", href);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return strdup(href+1);
|
||||
}
|
||||
|
||||
static void create_locks(void)
|
||||
{
|
||||
thread_mutex_create(&_locks.relay_lock);
|
||||
@ -595,6 +608,7 @@ listener_t *config_clear_listener(listener_t *listener)
|
||||
{
|
||||
next = listener->next;
|
||||
if (listener->id) xmlFree(listener->id);
|
||||
if (listener->on_behalf_of) free(listener->on_behalf_of);
|
||||
if (listener->bind_address) xmlFree(listener->bind_address);
|
||||
if (listener->shoutcast_mount) xmlFree(listener->shoutcast_mount);
|
||||
free (listener);
|
||||
@ -1761,6 +1775,12 @@ static void _parse_listen_socket(xmlDocPtr doc,
|
||||
|
||||
listener->id = (char *)xmlGetProp(node, XMLSTR("id"));
|
||||
|
||||
tmp = (char*)xmlGetProp(node, XMLSTR("on-behalf-of"));
|
||||
if (tmp) {
|
||||
listener->on_behalf_of = config_href_to_id(tmp);
|
||||
xmlFree(tmp);
|
||||
}
|
||||
|
||||
tmp = (char *)xmlGetProp(node, XMLSTR("type"));
|
||||
listener->type = config_str_to_listener_type(tmp);
|
||||
xmlFree(tmp);
|
||||
@ -2511,6 +2531,9 @@ listener_t *config_copy_listener_one(const listener_t *listener) {
|
||||
n->so_sndbuf = listener->so_sndbuf;
|
||||
n->type = listener->type;
|
||||
n->id = (char*)xmlStrdup(XMLSTR(listener->id));
|
||||
if (listener->on_behalf_of) {
|
||||
n->on_behalf_of = strdup(listener->on_behalf_of);
|
||||
}
|
||||
n->bind_address = (char*)xmlStrdup(XMLSTR(listener->bind_address));
|
||||
n->shoutcast_compat = listener->shoutcast_compat;
|
||||
n->shoutcast_mount = (char*)xmlStrdup(XMLSTR(listener->shoutcast_mount));
|
||||
|
@ -156,6 +156,7 @@ typedef enum _listener_type_tag {
|
||||
typedef struct _listener_t {
|
||||
struct _listener_t *next;
|
||||
char *id;
|
||||
char *on_behalf_of;
|
||||
listener_type_t type;
|
||||
int port;
|
||||
int so_sndbuf;
|
||||
|
@ -53,6 +53,7 @@ struct listensocket_tag {
|
||||
sock_t sock;
|
||||
};
|
||||
|
||||
static listensocket_t * listensocket_container_get_by_id(listensocket_container_t *self, const char *id);
|
||||
static int listensocket_container_configure__unlocked(listensocket_container_t *self, const ice_config_t *config);
|
||||
static int listensocket_container_setup__unlocked(listensocket_container_t *self);
|
||||
static ssize_t listensocket_container_sockcount__unlocked(listensocket_container_t *self);
|
||||
@ -466,6 +467,29 @@ static ssize_t listensocket_container_sockcount__unlocked(listensocket_container
|
||||
return count;
|
||||
}
|
||||
|
||||
static listensocket_t * listensocket_container_get_by_id(listensocket_container_t *self, const char *id)
|
||||
{
|
||||
size_t i;
|
||||
const listener_t *listener;
|
||||
|
||||
for (i = 0; i < self->sock_len; i++) {
|
||||
if (self->sock[i] != NULL) {
|
||||
listener = listensocket_get_listener(self->sock[i]);
|
||||
if (listener) {
|
||||
if (strcmp(listener->id, id) == 0) {
|
||||
listensocket_release_listener(self->sock[i]);
|
||||
if (refobject_ref(self->sock[i]) == 0) {
|
||||
return self->sock[i];
|
||||
}
|
||||
}
|
||||
listensocket_release_listener(self->sock[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------- */
|
||||
|
||||
static void __listensocket_free(refobject_t self, void **userdata)
|
||||
@ -679,6 +703,16 @@ connection_t * listensocket_accept(listensocket_t *self, listensock
|
||||
memmove(ip, ip+7, strlen(ip+7)+1);
|
||||
}
|
||||
|
||||
ICECAST_LOG_DEBUG("Client on socket \"%H\".", self->listener->id);
|
||||
|
||||
if (self->listener->on_behalf_of) {
|
||||
ICECAST_LOG_DEBUG("This socket is acting on behalf of \"%H\"", self->listener->on_behalf_of);
|
||||
effective = listensocket_container_get_by_id(container, self->listener->on_behalf_of);
|
||||
if (!effective) {
|
||||
ICECAST_LOG_ERROR("Can not find listen socket with ID \"%H\". Will continue on behalf of myself.", self->listener->on_behalf_of);
|
||||
}
|
||||
}
|
||||
|
||||
if (!effective) {
|
||||
effective = self;
|
||||
refobject_ref(effective);
|
||||
|
Loading…
x
Reference in New Issue
Block a user