mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-11-03 04:17:17 -05:00
kh26 update. The 2 main issues are :-
possible corruption with short-send of non-ogg metadata, specifically the write merged block. the slave stream listing was not honouring non-hidden attributes or auth The smaller parts are mainly code re-organisation, a backward compatibility option and options for IP handling. svn path=/icecast/branches/kh/icecast/; revision=17364
This commit is contained in:
parent
8796ecc4e0
commit
d8753a5b99
12
NEWS
12
NEWS
@ -1,5 +1,6 @@
|
||||
Feature differences from SVN trunk
|
||||
|
||||
. FLV wrapping for mp3/aac listeners requesting it with ?type=.flv
|
||||
. define a fixed number of worker threads (default 1) for processing clients
|
||||
. allow for wildcards (*[] expansion) in mount-name and ban/allow files
|
||||
. can limit mountpoint by outgoing bandwidth as well as a max listeners count
|
||||
@ -16,6 +17,17 @@ Feature differences from SVN trunk
|
||||
any extra tags are show in the conf/icecast.xml.dist file
|
||||
|
||||
|
||||
2.3.2-kh26
|
||||
. fix possible content corruption on shoutcast metadata inserted streams if a short
|
||||
send occurs during metadata sending.
|
||||
. do not list non-hidden streams in /admin/stream[list|streams] and make sure auth
|
||||
applies to /admin/streams.
|
||||
. allow for the so-sndbuf option per-mount as well as on all connections.
|
||||
. old style bind-address setting (not listen-socket) was not working
|
||||
. allow a negative ban-client value to use the internal deny block of IPs to prevent
|
||||
more than 1 IP connecting at the same time.
|
||||
. small code changes for main worker thread
|
||||
|
||||
2.3.2-kh25
|
||||
. FLV clients could skip frames on a truncated write, leading to playback problems.
|
||||
. various client scheduling tunings, allows quicker reschedule when only some data
|
||||
|
@ -95,7 +95,7 @@
|
||||
#define PACKAGE_NAME "Icecast"
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "2.3.2-kh25"
|
||||
#define VERSION "2.3.2-kh26"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION VERSION
|
||||
|
@ -1,4 +1,4 @@
|
||||
AC_INIT([Icecast], [2.3.2-kh25], [karl@xiph.org])
|
||||
AC_INIT([Icecast], [2.3.2-kh26], [karl@xiph.org])
|
||||
|
||||
LT_INIT
|
||||
AC_PREREQ(2.59)
|
||||
|
20
src/auth.c
20
src/auth.c
@ -412,6 +412,10 @@ static int add_authenticated_listener (const char *mount, mount_proxy *mountinfo
|
||||
|
||||
client->flags |= CLIENT_AUTHENTICATED;
|
||||
|
||||
/* some win32 setups do not do TCP win scaling well, so allow an override */
|
||||
if (mountinfo && mountinfo->so_sndbuf > 0)
|
||||
sock_set_send_buffer (client->connection.sock, mountinfo->so_sndbuf);
|
||||
|
||||
/* check whether we are processing a streamlist request for slaves */
|
||||
if (strcmp (mount, "/admin/streams") == 0)
|
||||
{
|
||||
@ -534,10 +538,15 @@ void auth_add_listener (const char *mount, client_t *client)
|
||||
{
|
||||
if (mountinfo->skip_accesslog)
|
||||
client->flags |= CLIENT_SKIP_ACCESSLOG;
|
||||
if (mountinfo->ban_client || mountinfo->no_mount)
|
||||
if (mountinfo->ban_client)
|
||||
{
|
||||
DEBUG1 ("ban client value is %d", mountinfo->ban_client);
|
||||
if (mountinfo->ban_client < 0)
|
||||
client->flags |= CLIENT_IP_BAN_LIFT;
|
||||
connection_add_banned_ip (client->connection.ip, mountinfo->ban_client);
|
||||
}
|
||||
if (mountinfo->no_mount)
|
||||
{
|
||||
if (mountinfo->ban_client)
|
||||
connection_add_banned_ip (client->connection.ip, mountinfo->ban_client);
|
||||
config_release_config ();
|
||||
client_send_403 (client, "mountpoint unavailable");
|
||||
return;
|
||||
@ -562,7 +571,10 @@ void auth_add_listener (const char *mount, client_t *client)
|
||||
}
|
||||
else
|
||||
{
|
||||
add_authenticated_listener (mount, mountinfo, client);
|
||||
if (client->flags & CLIENT_AUTHENTICATED)
|
||||
add_authenticated_listener (mount, mountinfo, client);
|
||||
else
|
||||
client_send_403 (client, "Forbidden");
|
||||
}
|
||||
config_release_config ();
|
||||
}
|
||||
|
@ -792,6 +792,7 @@ static int _parse_mount (xmlNodePtr node, void *arg)
|
||||
config_get_bool, &mount->url_ogg_meta },
|
||||
{ "no-mount", config_get_bool, &mount->no_mount },
|
||||
{ "ban-client", config_get_int, &mount->ban_client },
|
||||
{ "so-sndbuf", config_get_int, &mount->so_sndbuf },
|
||||
{ "hidden", config_get_bool, &mount->hidden },
|
||||
{ "authentication", auth_get_authenticator, &mount->auth },
|
||||
{ "on-connect", config_get_str, &mount->on_connect },
|
||||
@ -842,7 +843,9 @@ static int _parse_mount (xmlNodePtr node, void *arg)
|
||||
if (mount->url_ogg_meta)
|
||||
mount->ogg_passthrough = 0;
|
||||
if (mount->queue_block_size < 100)
|
||||
mount->queue_block_size = 2900;
|
||||
mount->queue_block_size = 1400;
|
||||
if (mount->ban_client < 0)
|
||||
mount->no_mount = 0;
|
||||
|
||||
mount->next = config->mounts;
|
||||
config->mounts = mount;
|
||||
@ -1061,6 +1064,7 @@ static int _parse_listen_sock (xmlNodePtr node, void *arg)
|
||||
|
||||
static int _parse_root (xmlNodePtr node, ice_config_t *config)
|
||||
{
|
||||
char *bindaddress = NULL;
|
||||
struct cfg_tag icecast_tags[] =
|
||||
{
|
||||
{ "location", config_get_str, &config->location },
|
||||
@ -1070,6 +1074,7 @@ static int _parse_root (xmlNodePtr node, ice_config_t *config)
|
||||
{ "source-password", config_get_str, &config->source_password },
|
||||
{ "hostname", config_get_str, &config->hostname },
|
||||
{ "port", config_get_int, &config->port },
|
||||
{ "bind-address", config_get_str, &bindaddress },
|
||||
{ "fileserve", config_get_bool, &config->fileserve },
|
||||
{ "relays-on-demand", config_get_bool, &config->on_demand },
|
||||
{ "master-server", config_get_str, &config->master_server },
|
||||
@ -1104,8 +1109,22 @@ static int _parse_root (xmlNodePtr node, ice_config_t *config)
|
||||
config->max_redirects = 1;
|
||||
if (config->listen_sock_count == 0)
|
||||
{
|
||||
WARN0 ("No listen-socket defintions");
|
||||
return -1;
|
||||
if (config->port)
|
||||
{
|
||||
listener_t *listener = calloc (1, sizeof(listener_t));
|
||||
listener->refcount = 1;
|
||||
listener->port = config->port;
|
||||
listener->qlen = ICE_LISTEN_QUEUE;
|
||||
listener->bind_address = (char*)xmlStrdup (XMLSTR(bindaddress));
|
||||
listener->next = config->listen_sock;
|
||||
config->listen_sock = listener;
|
||||
config->listen_sock_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN0 ("No listen-socket defintions");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -101,6 +101,7 @@ typedef struct _mount_proxy {
|
||||
int ban_client; /* do we add a client on this to the ban list automatically */
|
||||
int no_mount; /* Do we permit direct requests of this mountpoint? (or only
|
||||
indirect, through fallbacks) */
|
||||
int so_sndbuf; /* TCP send buffer size for new clients */
|
||||
int burst_size; /* amount to send to a new client if possible, -1 take
|
||||
* from global setting */
|
||||
unsigned int queue_size_limit;
|
||||
|
160
src/client.c
160
src/client.c
@ -101,6 +101,13 @@ void client_destroy(client_t *client)
|
||||
if (client->respcode > 0 && client->parser)
|
||||
logging_access(client);
|
||||
|
||||
if (client->flags & CLIENT_IP_BAN_LIFT)
|
||||
{
|
||||
INFO1 ("lifting IP ban on client at %s", client->connection.ip);
|
||||
connection_release_banned_ip (client->connection.ip);
|
||||
client->flags &= ~CLIENT_IP_BAN_LIFT;
|
||||
}
|
||||
|
||||
connection_close (&client->connection);
|
||||
if (client->parser)
|
||||
httpp_destroy (client->parser);
|
||||
@ -372,6 +379,7 @@ void client_add_worker (client_t *client)
|
||||
worker_wakeup (handler);
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#define pipe_create sock_create_pipe_emulation
|
||||
#define pipe_write(A, B, C) send(A, B, C, 0)
|
||||
@ -382,26 +390,6 @@ void client_add_worker (client_t *client)
|
||||
#define pipe_read read
|
||||
#endif
|
||||
|
||||
static void worker_move_clients (worker_t *from)
|
||||
{
|
||||
client_t *client = from->clients;
|
||||
|
||||
if (workers == NULL || from == NULL || workers->running == 0)
|
||||
return;
|
||||
while (client)
|
||||
{
|
||||
client->worker = workers;
|
||||
client = client->next_on_worker;
|
||||
}
|
||||
thread_spin_lock (&workers->lock);
|
||||
*workers->pending_clients_tail = from->clients;
|
||||
workers->pending_clients_tail = from->last_p;
|
||||
workers->pending_count += from->count;
|
||||
thread_spin_unlock (&workers->lock);
|
||||
from->count = 0;
|
||||
from->clients = NULL;
|
||||
from->last_p = &from->clients;
|
||||
}
|
||||
|
||||
static void worker_add_pending_clients (worker_t *worker)
|
||||
{
|
||||
@ -440,87 +428,113 @@ static void worker_wait (worker_t *worker)
|
||||
worker_add_pending_clients (worker);
|
||||
|
||||
worker->time_ms = timing_get_time();
|
||||
worker->current_time.tv_sec = worker->time_ms/1000;
|
||||
worker->current_time.tv_sec = (time_t)(worker->time_ms/1000);
|
||||
worker->current_time.tv_nsec = worker->current_time.tv_sec - (worker->time_ms*1000);
|
||||
worker->wakeup_ms = worker->time_ms + 60000;
|
||||
}
|
||||
|
||||
|
||||
void *worker (void *arg)
|
||||
static void worker_relocate_clients (worker_t *worker)
|
||||
{
|
||||
worker_t *handler = arg;
|
||||
client_t *client, **prevp;
|
||||
long prev_count = -1;
|
||||
|
||||
handler->running = 1;
|
||||
handler->wakeup_ms = (int64_t)0;
|
||||
prevp = &handler->clients;
|
||||
while (1)
|
||||
if (workers == NULL)
|
||||
return;
|
||||
while (worker->count || worker->pending_count)
|
||||
{
|
||||
if (handler->running == 0)
|
||||
{
|
||||
handler->wakeup_ms = handler->time_ms + 50;
|
||||
worker_add_pending_clients (handler);
|
||||
if (handler->count == 0)
|
||||
break;
|
||||
worker_move_clients (handler);
|
||||
}
|
||||
if (prev_count != handler->count)
|
||||
{
|
||||
DEBUG2 ("%p now has %d clients", handler, handler->count);
|
||||
prev_count = handler->count;
|
||||
}
|
||||
client_t *client = worker->clients, **prevp = &worker->clients;
|
||||
|
||||
worker_wait (handler);
|
||||
client = handler->clients;
|
||||
prevp = &handler->clients;
|
||||
worker->wakeup_ms = worker->time_ms + 150;
|
||||
while (client)
|
||||
{
|
||||
if (client->worker != handler)
|
||||
abort();
|
||||
if (client->flags & CLIENT_ACTIVE)
|
||||
{
|
||||
client->worker = workers;
|
||||
prevp = &client->next_on_worker;
|
||||
}
|
||||
else
|
||||
{
|
||||
*prevp = client->next_on_worker;
|
||||
worker_add_client (worker, client);
|
||||
worker->count--;
|
||||
}
|
||||
client = *prevp;
|
||||
}
|
||||
if (worker->clients)
|
||||
{
|
||||
thread_spin_lock (&workers->lock);
|
||||
*workers->pending_clients_tail = worker->clients;
|
||||
workers->pending_clients_tail = prevp;
|
||||
workers->pending_count += worker->count;
|
||||
thread_spin_unlock (&workers->lock);
|
||||
worker_wakeup (workers);
|
||||
worker->clients = NULL;
|
||||
worker->last_p = &worker->clients;
|
||||
worker->count = 0;
|
||||
}
|
||||
worker_wait (worker);
|
||||
}
|
||||
}
|
||||
|
||||
void *worker (void *arg)
|
||||
{
|
||||
worker_t *worker = arg;
|
||||
long prev_count = -1;
|
||||
|
||||
worker->running = 1;
|
||||
worker->wakeup_ms = (int64_t)0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
client_t *client = worker->clients, **prevp = &worker->clients;
|
||||
|
||||
if (prev_count != worker->count)
|
||||
{
|
||||
DEBUG2 ("%p now has %d clients", worker, worker->count);
|
||||
prev_count = worker->count;
|
||||
}
|
||||
while (client)
|
||||
{
|
||||
if (client->worker != worker) abort();
|
||||
/* process client details but skip those that are not ready yet */
|
||||
if (client->flags & CLIENT_ACTIVE)
|
||||
{
|
||||
if (client->schedule_ms <= handler->time_ms+10)
|
||||
int ret = 0;
|
||||
client_t *nx = client->next_on_worker;
|
||||
|
||||
if (client->schedule_ms <= worker->time_ms+10)
|
||||
{
|
||||
int ret;
|
||||
client_t *nx = client->next_on_worker;
|
||||
|
||||
client->schedule_ms = handler->time_ms;
|
||||
client->schedule_ms = worker->time_ms;
|
||||
ret = client->ops->process (client);
|
||||
|
||||
/* special handler, client has moved away to another worker */
|
||||
if (ret > 0)
|
||||
{
|
||||
handler->count--;
|
||||
if (nx == NULL) /* moved last client */
|
||||
handler->last_p = prevp;
|
||||
*prevp = nx;
|
||||
client = nx;
|
||||
continue;
|
||||
}
|
||||
if (ret < 0)
|
||||
{
|
||||
client_t *to_go = client;
|
||||
*prevp = to_go->next_on_worker;
|
||||
client->next_on_worker = NULL;
|
||||
client->worker = NULL;
|
||||
handler->count--;
|
||||
if (client->ops->release)
|
||||
client->ops->release (client);
|
||||
client = *prevp;
|
||||
if (client == NULL)
|
||||
handler->last_p = prevp;
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
worker->count--;
|
||||
if (nx == NULL) /* is this the last client */
|
||||
worker->last_p = prevp;
|
||||
client = *prevp = nx;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (client->schedule_ms < handler->wakeup_ms)
|
||||
handler->wakeup_ms = client->schedule_ms;
|
||||
if (client->schedule_ms < worker->wakeup_ms)
|
||||
worker->wakeup_ms = client->schedule_ms;
|
||||
}
|
||||
prevp = &client->next_on_worker;
|
||||
client = *prevp;
|
||||
}
|
||||
if (worker->running == 0)
|
||||
{
|
||||
if (global.running == ICE_RUNNING)
|
||||
break;
|
||||
if (worker->count == 0 && worker->pending_count == 0)
|
||||
break;
|
||||
}
|
||||
worker_wait (worker);
|
||||
}
|
||||
worker_relocate_clients (worker);
|
||||
INFO0 ("shutting down");
|
||||
return NULL;
|
||||
}
|
||||
|
@ -149,6 +149,7 @@ void worker_wakeup (worker_t *worker);
|
||||
#define CLIENT_HAS_INTRO_CONTENT (040)
|
||||
#define CLIENT_SKIP_ACCESSLOG (0100)
|
||||
#define CLIENT_HAS_MOVED (0200)
|
||||
#define CLIENT_IP_BAN_LIFT (0400)
|
||||
#define CLIENT_FORMAT_BIT (01000)
|
||||
|
||||
#endif /* __CLIENT_H__ */
|
||||
|
@ -356,7 +356,7 @@ static void add_banned_ip (avl_tree *t, const char *ip, time_t now)
|
||||
|
||||
void connection_add_banned_ip (const char *ip, int duration)
|
||||
{
|
||||
time_t timeout = -1;
|
||||
time_t timeout = 0;
|
||||
if (duration > 0)
|
||||
timeout = time(NULL) + duration;
|
||||
|
||||
@ -368,6 +368,16 @@ void connection_add_banned_ip (const char *ip, int duration)
|
||||
}
|
||||
}
|
||||
|
||||
void connection_release_banned_ip (const char *ip)
|
||||
{
|
||||
if (banned_ip.contents)
|
||||
{
|
||||
global_lock();
|
||||
avl_delete (banned_ip.contents, (void*)ip, free_filtered_line);
|
||||
global_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void connection_stats (void)
|
||||
{
|
||||
if (banned_ip.contents)
|
||||
|
@ -61,6 +61,7 @@ int connection_init (connection_t *con, sock_t sock, const char *addr);
|
||||
int connection_complete_source (struct source_tag *source);
|
||||
void connection_uses_ssl (connection_t *con);
|
||||
void connection_add_banned_ip (const char *ip, int duration);
|
||||
void connection_release_banned_ip (const char *ip);
|
||||
void connection_stats (void);
|
||||
#ifdef HAVE_OPENSSL
|
||||
int connection_read_ssl (connection_t *con, void *buf, size_t len);
|
||||
|
@ -342,31 +342,43 @@ static int send_stream_metadata (client_t *client, refbuf_t *refbuf, unsigned in
|
||||
/* If there is a change in metadata then send it else
|
||||
* send a single zero value byte in its place
|
||||
*/
|
||||
if (associated && associated != client_mp3->associated)
|
||||
if (client->flags & CLIENT_IN_METADATA)
|
||||
{
|
||||
metadata = associated->data + client_mp3->metadata_offset;
|
||||
meta_len = associated->len - client_mp3->metadata_offset;
|
||||
client->flags &= ~CLIENT_USING_BLANK_META;
|
||||
refbuf_release (client_mp3->associated);
|
||||
refbuf_addref (associated);
|
||||
client_mp3->associated = associated;
|
||||
/* rare but possible case of resuming a send part way through a metadata block */
|
||||
metadata = client_mp3->associated->data + client_mp3->metadata_offset;
|
||||
meta_len = client_mp3->associated->len - client_mp3->metadata_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (associated || ((client->flags & CLIENT_USING_BLANK_META) &&
|
||||
client_mp3->metadata_offset == 0))
|
||||
if (associated && associated != client_mp3->associated)
|
||||
{
|
||||
metadata = "\0";
|
||||
meta_len = 1;
|
||||
/* change of metadata found, but we do not release the blank one as that
|
||||
* could race against the source client use of it. */
|
||||
metadata = associated->data;
|
||||
meta_len = associated->len;
|
||||
if (client->flags & CLIENT_USING_BLANK_META)
|
||||
client->flags &= ~CLIENT_USING_BLANK_META;
|
||||
else
|
||||
refbuf_release (client_mp3->associated);
|
||||
refbuf_addref (associated);
|
||||
client_mp3->associated = associated;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *meta = blank_meta.data;
|
||||
metadata = meta + client_mp3->metadata_offset;
|
||||
meta_len = blank_meta.len - client_mp3->metadata_offset;
|
||||
client->flags |= CLIENT_USING_BLANK_META;
|
||||
refbuf_release (client_mp3->associated);
|
||||
client_mp3->associated = NULL;
|
||||
if (associated) /* previously sent metadata does not need to be sent again */
|
||||
{
|
||||
metadata = "\0";
|
||||
meta_len = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *meta = blank_meta.data;
|
||||
metadata = meta + client_mp3->metadata_offset;
|
||||
meta_len = blank_meta.len - client_mp3->metadata_offset;
|
||||
client->flags |= CLIENT_USING_BLANK_META;
|
||||
refbuf_release (client_mp3->associated);
|
||||
client_mp3->associated = &blank_meta;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* if there is normal stream data to send as well as metadata then try
|
||||
@ -389,6 +401,8 @@ static int send_stream_metadata (client_t *client, refbuf_t *refbuf, unsigned in
|
||||
client->flags |= CLIENT_IN_METADATA;
|
||||
client->schedule_ms += 200;
|
||||
}
|
||||
else
|
||||
client->flags &= ~CLIENT_IN_METADATA;
|
||||
client_mp3->since_meta_block = 0;
|
||||
client->pos += remaining;
|
||||
client->queue_pos += remaining;
|
||||
@ -401,6 +415,7 @@ static int send_stream_metadata (client_t *client, refbuf_t *refbuf, unsigned in
|
||||
client->pos += ret;
|
||||
client->queue_pos += ret;
|
||||
}
|
||||
client->flags |= CLIENT_IN_METADATA;
|
||||
return ret > 0 ? ret : 0;
|
||||
}
|
||||
ret = client_send_bytes (client, metadata, meta_len);
|
||||
@ -434,15 +449,6 @@ static int format_mp3_write_buf_to_client (client_t *client)
|
||||
|
||||
do
|
||||
{
|
||||
/* send any unwritten metadata to the client */
|
||||
if (client->flags & CLIENT_IN_METADATA)
|
||||
{
|
||||
ret = send_stream_metadata (client, refbuf, 0);
|
||||
|
||||
if (client->flags & CLIENT_IN_METADATA)
|
||||
break;
|
||||
written += ret;
|
||||
}
|
||||
/* see if we need to send the current metadata to the client */
|
||||
if (client_mp3->interval)
|
||||
{
|
||||
@ -459,6 +465,7 @@ static int format_mp3_write_buf_to_client (client_t *client)
|
||||
len -= remaining;
|
||||
if (ret <= (int)remaining || len > client_mp3->interval)
|
||||
break;
|
||||
written += ret;
|
||||
}
|
||||
}
|
||||
/* write any mp3, maybe after the metadata block */
|
||||
|
41
src/fserve.c
41
src/fserve.c
@ -677,6 +677,7 @@ static int prefile_send (client_t *client)
|
||||
{
|
||||
refbuf_t *refbuf = client->refbuf;
|
||||
int loop = 6, bytes, written = 0;
|
||||
worker_t *worker = client->worker;
|
||||
|
||||
while (loop)
|
||||
{
|
||||
@ -733,15 +734,15 @@ static int prefile_send (client_t *client)
|
||||
bytes = client->check_buffer (client);
|
||||
if (bytes < 0)
|
||||
{
|
||||
client->schedule_ms = client->worker->time_ms + 300;
|
||||
client->schedule_ms = worker->time_ms + 300;
|
||||
return 0;
|
||||
}
|
||||
written += bytes;
|
||||
global_add_bitrates (global.out_bitrate, bytes, client->worker->time_ms);
|
||||
global_add_bitrates (global.out_bitrate, bytes, worker->time_ms);
|
||||
if (written > 30000)
|
||||
break;
|
||||
}
|
||||
client->schedule_ms = client->worker->time_ms + 100;
|
||||
client->schedule_ms = worker->time_ms + 100;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -774,9 +775,11 @@ static int file_send (client_t *client)
|
||||
refbuf_t *refbuf = client->refbuf;
|
||||
int loop = 6, bytes, written = 0, ret = 0;
|
||||
fh_node *fh = client->shared_data;
|
||||
time_t now = client->worker->current_time.tv_sec;
|
||||
worker_t *worker = client->worker;
|
||||
time_t now;
|
||||
|
||||
client->schedule_ms = client->worker->time_ms;
|
||||
client->schedule_ms = worker->time_ms;
|
||||
now = worker->current_time.tv_sec;
|
||||
/* slowdown if max bandwidth is exceeded, but allow for short-lived connections to avoid
|
||||
* this, eg admin requests */
|
||||
if (throttle_sends > 1 && now - client->connection.con_time > 1)
|
||||
@ -816,13 +819,17 @@ static int throttled_file_send (client_t *client)
|
||||
refbuf_t *refbuf = client->refbuf;
|
||||
int bytes;
|
||||
fh_node *fh = client->shared_data;
|
||||
time_t now = client->worker->current_time.tv_sec;
|
||||
unsigned long secs = now - client->timer_start;
|
||||
unsigned int rate = secs ? ((client->counter+1400)/secs) : 0;
|
||||
time_t now;
|
||||
worker_t *worker = client->worker;
|
||||
unsigned long secs;
|
||||
unsigned int rate = 0;
|
||||
unsigned int limit = fh->finfo.limit;
|
||||
|
||||
if (fserve_running == 0 || client->connection.error)
|
||||
return -1;
|
||||
now = worker->current_time.tv_sec;
|
||||
secs = now - client->timer_start;
|
||||
client->schedule_ms = worker->time_ms;
|
||||
if (client->connection.discon_time && now >= client->connection.discon_time)
|
||||
return -1;
|
||||
if (fh->finfo.fallback)
|
||||
@ -830,15 +837,17 @@ static int throttled_file_send (client_t *client)
|
||||
fserve_move_listener (client);
|
||||
return 0;
|
||||
}
|
||||
thread_mutex_lock (&fh->lock);
|
||||
if (client->flags & CLIENT_WANTS_FLV) /* increase limit for flv clients as wrapping takes more space */
|
||||
limit = (unsigned long)(limit * 1.02);
|
||||
if (secs)
|
||||
rate = (client->counter+1400)/secs;
|
||||
thread_mutex_lock (&fh->lock);
|
||||
if (rate > limit)
|
||||
{
|
||||
client->schedule_ms = client->worker->time_ms + (1000*(rate - fh->finfo.limit))/fh->finfo.limit;
|
||||
rate_add (fh->format->out_bitrate, 0, client->worker->time_ms);
|
||||
client->schedule_ms += (1000*(rate - limit))/limit;
|
||||
rate_add (fh->format->out_bitrate, 0, worker->time_ms);
|
||||
thread_mutex_unlock (&fh->lock);
|
||||
global_add_bitrates (global.out_bitrate, 0, client->worker->time_ms);
|
||||
global_add_bitrates (global.out_bitrate, 0, worker->time_ms);
|
||||
return 0;
|
||||
}
|
||||
if (fh->stats_update <= now)
|
||||
@ -855,7 +864,7 @@ static int throttled_file_send (client_t *client)
|
||||
thread_mutex_unlock (&fh->lock);
|
||||
client->intro_offset = 0;
|
||||
client->pos = refbuf->len = 0;
|
||||
client->schedule_ms = client->worker->time_ms + 150;
|
||||
client->schedule_ms += 150;
|
||||
return 0;
|
||||
}
|
||||
client->pos = 0;
|
||||
@ -863,11 +872,11 @@ static int throttled_file_send (client_t *client)
|
||||
bytes = client->check_buffer (client);
|
||||
if (bytes < 0)
|
||||
bytes = 0;
|
||||
rate_add (fh->format->out_bitrate, bytes, client->worker->time_ms);
|
||||
rate_add (fh->format->out_bitrate, bytes, worker->time_ms);
|
||||
thread_mutex_unlock (&fh->lock);
|
||||
global_add_bitrates (global.out_bitrate, bytes, client->worker->time_ms);
|
||||
global_add_bitrates (global.out_bitrate, bytes, worker->time_ms);
|
||||
client->counter += bytes;
|
||||
client->schedule_ms = client->worker->time_ms + (1000/(fh->finfo.limit/1400*2));
|
||||
client->schedule_ms += (1000/(limit/1400*2));
|
||||
|
||||
/* progessive slowdown if max bandwidth is exceeded. */
|
||||
if (throttle_sends > 1)
|
||||
|
@ -1345,6 +1345,7 @@ static void relay_release (client_t *client)
|
||||
static int relay_startup (client_t *client)
|
||||
{
|
||||
relay_server *relay = get_relay_details (client);
|
||||
worker_t *worker = client->worker;
|
||||
|
||||
if (relay->cleanup)
|
||||
{
|
||||
@ -1356,7 +1357,7 @@ static int relay_startup (client_t *client)
|
||||
}
|
||||
if (global.running != ICE_RUNNING)
|
||||
return 0; /* wait for cleanup */
|
||||
if (relay->running == 0 || relay->start > client->worker->current_time.tv_sec)
|
||||
if (relay->running == 0 || relay->start > worker->current_time.tv_sec)
|
||||
{
|
||||
client->schedule_ms = client->worker->time_ms + 1000;
|
||||
return 0;
|
||||
@ -1368,7 +1369,7 @@ static int relay_startup (client_t *client)
|
||||
int start_relay = src->listeners; // 0 or non-zero
|
||||
|
||||
src->flags |= SOURCE_ON_DEMAND;
|
||||
if (client->worker->current_time.tv_sec % 10 == 0)
|
||||
if (worker->current_time.tv_sec % 10 == 0)
|
||||
{
|
||||
mount_proxy * mountinfo = config_find_mount (config_get_config(), src->mount);
|
||||
if (mountinfo && mountinfo->fallback_mount)
|
||||
|
@ -1103,7 +1103,7 @@ refbuf_t *stats_get_streams (int prepend)
|
||||
int ret;
|
||||
stats_source_t *source = (stats_source_t *)node->key;
|
||||
|
||||
if (source->flags & STATS_SLAVE)
|
||||
if ((source->flags & STATS_HIDDEN) == 0)
|
||||
{
|
||||
if (remaining <= strlen (source->source) + prelen + 3)
|
||||
{
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
[Setup]
|
||||
AppName=Icecast2-KH
|
||||
AppVerName=Icecast v2.3.2-kh25
|
||||
AppVerName=Icecast v2.3.2-kh26
|
||||
AppPublisherURL=http://www.icecast.org
|
||||
AppSupportURL=http://www.icecast.org
|
||||
AppUpdatesURL=http://www.icecast.org
|
||||
@ -13,7 +13,7 @@ AllowNoIcons=yes
|
||||
LicenseFile=..\COPYING
|
||||
InfoAfterFile=..\README
|
||||
OutputDir=.
|
||||
OutputBaseFilename=icecast2_win32_v2.3.2-kh25_setup
|
||||
OutputBaseFilename=icecast2_win32_v2.3.2-kh26
|
||||
WizardImageFile=icecast2logo2.bmp
|
||||
WizardImageStretch=no
|
||||
VersionInfoVersion=2.3.2
|
||||
@ -68,4 +68,3 @@ Filename: "{app}\icecastService.exe"; Parameters: "install ""{app}""";Descriptio
|
||||
[UninstallRun]
|
||||
Filename: "{app}\icecastService.exe"; Parameters: "remove"
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user