Commit ccdef66b authored by Roger Dingledine's avatar Roger Dingledine
Browse files

new link padding scheme

we're now much more robust when bandwidth varies: instead of forcing a
fixed bandwidth on the link, we instead use what the link will give us,
up to our bandwidth.


svn:r53
parent 53cec4ca
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -364,6 +364,10 @@ int connection_state_is_open(connection_t *conn) {

void connection_send_cell(connection_t *conn) {
  cell_t cell;
  int bytes_in_full_flushlen;

  /* this function only gets called if options.LinkPadding is 1 */
  assert(options.LinkPadding == 1);

  assert(conn);

@@ -385,7 +389,17 @@ void connection_send_cell(connection_t *conn) {
  }
#endif

#if 1 /* experimental code, that sends padding cells too. 'probably' works :) */
  connection_increment_send_timeval(conn); /* update when we'll send the next cell */

  bytes_in_full_flushlen = conn->bandwidth / 100; /* 10ms worth */
  if(bytes_in_full_flushlen < 10*sizeof(cell_t))
    bytes_in_full_flushlen = 10*sizeof(cell_t); /* but at least 10 cells worth */

  if(conn->outbuf_flushlen > bytes_in_full_flushlen - sizeof(cell_t)) {
    /* if we would exceed bytes_in_full_flushlen by adding a new cell */
    return;
  }

  if(conn->outbuf_datalen - conn->outbuf_flushlen < sizeof(cell_t)) {
    /* we need to queue a padding cell first */
    memset(&cell,0,sizeof(cell_t));
@@ -395,9 +409,7 @@ void connection_send_cell(connection_t *conn) {

  conn->outbuf_flushlen += sizeof(cell_t); /* instruct it to send a cell */
  connection_watch_events(conn, POLLOUT | POLLIN);
#endif

  connection_increment_send_timeval(conn); /* update when we'll send the next cell */
}

void connection_increment_send_timeval(connection_t *conn) {
+6 −4
Original line number Diff line number Diff line
@@ -344,10 +344,10 @@ int prepare_for_poll(int *timeout) {
      if(!connection_state_is_open(tmpconn))
        continue; /* only conns in state 'open' have a valid send_timeval */ 
      while(tv_cmp(&tmpconn->send_timeval,&now) <= 0) { /* send_timeval has already passed, let it send a cell */
        log(LOG_DEBUG,"prepare_for_poll(): doing backlogged connection_send_cell on socket %d (%d ms old)",tmpconn->s,
          (now.tv_sec - tmpconn->send_timeval.tv_sec)*1000 +
          (now.tv_usec - tmpconn->send_timeval.tv_usec)/1000
        );
//        log(LOG_DEBUG,"prepare_for_poll(): doing backlogged connection_send_cell on socket %d (%d ms old)",tmpconn->s,
//         (now.tv_sec - tmpconn->send_timeval.tv_sec)*1000 +
//         (now.tv_usec - tmpconn->send_timeval.tv_usec)/1000
//        );
        connection_send_cell(tmpconn);
      }
      if(!conn || tv_cmp(&tmpconn->send_timeval, &soonest) < 0) { /* this is the best choice so far */
@@ -424,11 +424,13 @@ int do_main_loop(void) {
    /* poll until we have an event, or it's time to do something */
    poll_result = poll(poll_array, nfds, timeout);

#if 0 /* let catch() handle things like ^c, and otherwise don't worry about it */
    if(poll_result < 0) {
      log(LOG_ERR,"do_main_loop(): poll failed.");
      if(errno != EINTR) /* let the program survive things like ^z */
        return -1;
    }
#endif

    if(poll_result > 0) { /* we have at least one connection to deal with */
      /* do all the reads first, so we can detect closed sockets */