[icecast-dev] Re: PATCH: increase network congestion resilience

Ricardo Galli gallir at uib.es
Fri Jan 17 11:55:40 PST 2003



On Friday 17 January 2003 20:17, Karl Heyes shaped the electrons to say:
> I would suggest a slightly different approach.
>
> Instead of increasing the syscall overhead for all sockets, trapping
> for uncommon cases.  Try the sock_write_bytes and if that is
> continuously having to queue (ie not all data can be sent) then display
> the warning, maybe make it a run-time option (default enabled).

Hi Karl,
        I will study it later. Do you have commit privileges? If so, 
I can send you also a patch to solve a memory leak bug (refbufs 
not released) and propose a bigger change: move the logic of 
actually sending the buffers to another function, and also 
exploit it to do some flow control. 

It is working in my site since a year without a glitch. 
It's something like (for old icecast version):

<p>+int send_client_queue(client_t *client, int maxlag)
+{
+   refbuf_t *abuf;
+   long bytes, sbytes;
+   time_t now = time(NULL);
+
+   if (client->last_sent < (now - maxlag * 2)) {
+        client->con->error = 1; /* lame client or DoS */
+        return 1;
+   }
+   abuf = refbuf_queue_remove(&client->queue);
+   while (abuf) {
+       if (client->pos > 0)
+           bytes = abuf->len - client->pos;
+       else
+           bytes = abuf->len;

+       if( abuf->timestamp < (now - maxlag) /* packet too delayed, discard */ ) {
+           client->pos = 0;
+           printf("DEBUG: discarding %d bytes from queue!!! LAG=%d MAXLAG=%d\n", bytes, now - abuf->timestamp, maxlag);
+
+       } else {
+           sbytes = sock_write_bytes(client->con->sock, &abuf->data[client->pos], bytes);
+           if (sbytes > 0)  {
+               client->con->sent_bytes += sbytes;
+               client->last_sent = now;
+           }
+           if (sbytes < bytes) {
+               if (sbytes < 0 && !sock_recoverable(sock_error())) {
+                   printf("SOURCE: Client had unrecoverable error (%d) catching up (%ld/%ld)\n", sock_error(), sbytes, bytes);
+                   refbuf_release(abuf);
+                   client->con->error = 1;
+               } else {
+                   client->pos += sbytes>0?sbytes:0;
+                   /* put the refbuf back on top of the queue, since we didn't finish with it */
+                   refbuf_queue_insert(&client->queue, abuf);
+               }
+               return 1;
+           }
+       }
+       /* we're done with that refbuf, release it and reset the pos */
+       refbuf_release(abuf);
+       client->pos = 0;
+
+       abuf = refbuf_queue_remove(&client->queue);
+   }
+   return 0;
+}
+

...
+           data_done = send_client_queue(client, maxlag);

<p>
-- 
  ricardo galli       GPG id C8114D34

--- >8 ----
List archives:  http://www.xiph.org/archives/
icecast project homepage: http://www.icecast.org/
To unsubscribe from this list, send a message to 'icecast-dev-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.




More information about the Icecast-dev mailing list