From d8753a5b99f2374b026c91f20ac21f9fdf9a09b1 Mon Sep 17 00:00:00 2001 From: Karl Heyes Date: Tue, 17 Aug 2010 00:26:27 +0000 Subject: [PATCH] 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 --- NEWS | 12 ++++ config.h.vc6 | 2 +- configure.in | 2 +- src/auth.c | 20 ++++-- src/cfgfile.c | 25 ++++++- src/cfgfile.h | 1 + src/client.c | 160 ++++++++++++++++++++++++--------------------- src/client.h | 1 + src/connection.c | 12 +++- src/connection.h | 1 + src/format_mp3.c | 59 +++++++++-------- src/fserve.c | 41 +++++++----- src/slave.c | 5 +- src/stats.c | 2 +- win32/icecast2.iss | 5 +- 15 files changed, 217 insertions(+), 131 deletions(-) diff --git a/NEWS b/NEWS index 522d0e15..84078ab9 100644 --- a/NEWS +++ b/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 diff --git a/config.h.vc6 b/config.h.vc6 index 9e4342f0..88b76daf 100644 --- a/config.h.vc6 +++ b/config.h.vc6 @@ -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 diff --git a/configure.in b/configure.in index 5a8302bf..183ba547 100644 --- a/configure.in +++ b/configure.in @@ -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) diff --git a/src/auth.c b/src/auth.c index 3219d1eb..a8c03609 100644 --- a/src/auth.c +++ b/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 (); } diff --git a/src/cfgfile.c b/src/cfgfile.c index 464a8c85..c25ae346 100644 --- a/src/cfgfile.c +++ b/src/cfgfile.c @@ -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; } diff --git a/src/cfgfile.h b/src/cfgfile.h index 8616a676..26a0fed6 100644 --- a/src/cfgfile.h +++ b/src/cfgfile.h @@ -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; diff --git a/src/client.c b/src/client.c index 9f797abf..6bd5493f 100644 --- a/src/client.c +++ b/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; } diff --git a/src/client.h b/src/client.h index 76417311..a6b90bab 100644 --- a/src/client.h +++ b/src/client.h @@ -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__ */ diff --git a/src/connection.c b/src/connection.c index 1a3d4f53..ce1be03f 100644 --- a/src/connection.c +++ b/src/connection.c @@ -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) diff --git a/src/connection.h b/src/connection.h index 5267ec7d..2039deb2 100644 --- a/src/connection.h +++ b/src/connection.h @@ -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); diff --git a/src/format_mp3.c b/src/format_mp3.c index 742063fc..f8c60275 100644 --- a/src/format_mp3.c +++ b/src/format_mp3.c @@ -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 */ diff --git a/src/fserve.c b/src/fserve.c index 971eba2c..0eafcac7 100644 --- a/src/fserve.c +++ b/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) diff --git a/src/slave.c b/src/slave.c index 2d2a32c9..acabe741 100644 --- a/src/slave.c +++ b/src/slave.c @@ -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) diff --git a/src/stats.c b/src/stats.c index 4053d3b4..2c9b5710 100644 --- a/src/stats.c +++ b/src/stats.c @@ -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) { diff --git a/win32/icecast2.iss b/win32/icecast2.iss index 2b85f755..63364e2f 100644 --- a/win32/icecast2.iss +++ b/win32/icecast2.iss @@ -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" -