Пример #1
0
/**
 * Given a snap (likely read from a log) read a value as a double.
 * Upon failure will exit the program with error code EXIT_FAILURE.
 * 
 * 
 * @param name The name of the variable to read in Web100/Web10G.
 * @param snap A Web100/Web10G snap
 * @param group A Web100 group - ignored by Web10G should be NULL
 * @param agent A Web100 agent - ignored by Web10G should be NULL
 * 
 * @return The value of 'name' covnerted to a double.
 */
double tcp_stat_read_double(const char * name, tcp_stat_snap* snap,
                         tcp_stat_group* group, tcp_stat_agent* agent) {
#if USE_WEB100
  web100_var* var;
  char buf[256];
#elif USE_WEB10G
  estats_val val;
#endif

#if USE_WEB100
  if ((web100_agent_find_var_and_group(agent, name, &group,
                                       &var)) != WEB100_ERR_SUCCESS) {
    web100_perror("web100_agent_find_var_and_group");
    exit(EXIT_FAILURE);
  }

  if ((web100_snap_read(var, snap, buf)) != WEB100_ERR_SUCCESS) {
    web100_perror("web100_snap_read");
    exit(EXIT_FAILURE);
  }
  return atof(
              web100_value_to_text(web100_get_var_type(var),
                                   buf));
#elif USE_WEB10G
  int vartype = ESTATS_UNSIGNED32;
  /* ELAPSED_TIME not working in kernel patch, so use time on the 
   * snap */
  if (strcmp(name, ELAPSED_TIME) == 0) {
    val.masked = 0;
    val.uv32 = snap->tv.sec * 1000000 + snap->tv.usec - start_time;
  } else {
    vartype = web10g_find_val(snap, name, &val);
    if (vartype == -1) {
      printf("Bad vartype tcp_stat_read_double %s\n", name);
      exit(EXIT_FAILURE);
    }
  }
  switch (vartype) {
    case ESTATS_UNSIGNED64:
      return (double) val.uv64;
    case ESTATS_UNSIGNED32:
      return (double) val.uv32;
    case ESTATS_SIGNED32:
      return (double) val.sv32;
    case ESTATS_UNSIGNED16:
      return (double) val.uv16;
    case ESTATS_UNSIGNED8:
      return (double) val.uv8;
  }
  fprintf(stderr, "Bad vartype tcp_stat_read_double %s\n", name);
  exit(EXIT_FAILURE);
#endif
}
Пример #2
0
/**
 * Count the CWND peaks from a snapshot and record the minimal and maximum one.
 * Also record the number of transitions between increasing or decreasing
 * trends of the values.
 * @param agent Web100 agent used to track the connection
 * @param peaks Structure containing CWND peaks information
 * @param snap Web100 snapshot structure
 */
void findCwndPeaks(tcp_stat_agent* agent, CwndPeaks* peaks,
                   tcp_stat_snap* snap) {
    int CurCwnd;
#if USE_WEB100
    web100_group* group;
    web100_var* var;
    char tmpstr[256];
#elif USE_WEB10G
    struct estats_val value;
#endif

#if USE_WEB100
    web100_agent_find_var_and_group(agent, "CurCwnd", &group, &var);
    web100_snap_read(var, snap, tmpstr);
    CurCwnd = atoi(web100_value_to_text(web100_get_var_type(var), tmpstr));
#elif USE_WEB10G
    web10g_find_val(snap, "CurCwnd", &value);
    CurCwnd = value.uv32;
#endif

    if (slowStart) {
        if (CurCwnd < prevCWNDval) {
            slowStart = 0;
            peaks->max = prevCWNDval;
            peaks->amount = 1;
            decreasing = 1;
        }
    } else {
        // current congestion window < previous value, so, decreasing
        if (CurCwnd < prevCWNDval) {
            // update values based on actual values
            if (prevCWNDval > peaks->max) {
                peaks->max = prevCWNDval;
            }
            if (!decreasing) {
                peaks->amount += 1;
            }
            decreasing = 1;
            // current congestion window size > previous value,
        } else if (CurCwnd > prevCWNDval) {
            // not decreasing.
            if ((peaks->min == -1) || (prevCWNDval < peaks->min)) {
                peaks->min = prevCWNDval;
            }
            decreasing = 0;
        }
    }
    prevCWNDval = CurCwnd;
}
Пример #3
0
int
main(int argc, char *argv[])
{
    web100_agent* agent;
    web100_connection* conn;
    web100_group* group;
    web100_var* var;
    char buf[256];
    int cid;
    char** arg;

    argv0 = argv[0];

    if (argc < 3) {
        usage();
        exit(EXIT_FAILURE);
    }

    cid = atoi(argv[1]);
    
    if ((agent = web100_attach(WEB100_AGENT_TYPE_LOCAL, NULL)) == NULL) {
        web100_perror("web100_attach");
        exit(EXIT_FAILURE);
    }
    
    if ((conn = web100_connection_lookup(agent, cid)) == NULL) {
        web100_perror("web100_connection_lookup");
        exit(EXIT_FAILURE);
    }
   
    for (arg=&argv[2]; *arg; arg++) {
        if ((web100_agent_find_var_and_group(agent, *arg, &group, &var)) != WEB100_ERR_SUCCESS) {
            web100_perror("web100_agent_find_var_and_group");
            exit(EXIT_FAILURE);
        }

        if ((web100_raw_read(var, conn, buf)) != WEB100_ERR_SUCCESS) {
            web100_perror("web100_raw_read");
            exit(EXIT_FAILURE);
        }
    
        printf("%-20s: %s\n", *arg, web100_value_to_text(web100_get_var_type(var), buf));
    }

    web100_detach(agent);

    return 0;
}
Пример #4
0
/**
 * Get the title info from the snap. That is local address:port remote
 * address:port.
 * 
 * For Web10G this also logs the start_time because this is expected
 * to be the first snap captured.
 * 
 * @param snap A Web100/Web10G snap
 * @param agent A Web100 agent - ignored by Web10G should be NULL
 * @param group A Web100 group - ignored by Web10G should be NULL
 * @param title Upon return contains the string 
 *          "<localaddr>:<localport> --> <remoteaddr>"
 * @param remport Upon return contains the remote port as a string
 */
void get_title(tcp_stat_snap* snap, tcp_stat_agent* agent,
               tcp_stat_group* group, char* title, char* remport) {
#if USE_WEB100
  web100_var* var;
  char buf[128];

  if ((web100_agent_find_var_and_group(agent, "LocalAddress", &group, &var))
      != WEB100_ERR_SUCCESS) {
    web100_perror("web100_agent_find_var_and_group");
    exit(EXIT_FAILURE);
  }
  if ((web100_snap_read(var, snap, buf)) != WEB100_ERR_SUCCESS) {
    web100_perror("web100_snap_read");
    exit(EXIT_FAILURE);
  }
  strcpy(title, web100_value_to_text(web100_get_var_type(var), buf));
  strncat(title, ":", 1);
  if ((web100_agent_find_var_and_group(agent, "LocalPort", &group, &var))
      != WEB100_ERR_SUCCESS) {
    web100_perror("web100_agent_find_var_and_group");
    exit(EXIT_FAILURE);
  }
  if ((web100_snap_read(var, snap, buf)) != WEB100_ERR_SUCCESS) {
    web100_perror("web100_snap_read");
    exit(EXIT_FAILURE);
  }
  strcat(title, web100_value_to_text(web100_get_var_type(var), buf));
  strncat(title, " --> ", 5);
  if ((web100_agent_find_var_and_group(agent, "RemAddress", &group, &var))
      != WEB100_ERR_SUCCESS) {
    web100_perror("web100_agent_find_var_and_group");
    exit(EXIT_FAILURE);
  }
  if ((web100_snap_read(var, snap, buf)) != WEB100_ERR_SUCCESS) {
    web100_perror("web100_snap_read");
    exit(EXIT_FAILURE);
  }
  strcat(title, web100_value_to_text(web100_get_var_type(var), buf));
  if ((web100_agent_find_var_and_group(agent, "RemPort", &group, &var))
      != WEB100_ERR_SUCCESS) {
    web100_perror("web100_agent_find_var_and_group");
    exit(EXIT_FAILURE);
  }
  if ((web100_snap_read(var, snap, buf)) != WEB100_ERR_SUCCESS) {
    web100_perror("web100_snap_read");
    exit(EXIT_FAILURE);
  }
  strcpy(remport, web100_value_to_text(web100_get_var_type(var), buf));
  /* printf("%s:%s\n", title, remport); */
#elif USE_WEB10G
  estats_error* err = NULL;
  struct estats_connection_tuple_ascii tuple_ascii;

  /* Quite a convenient little function we have */
  if ((err = estats_connection_tuple_as_strings(&tuple_ascii,
                                            &snap->tuple)) != NULL) {
    /* If using the 3.5 kernel to make snaps it appears that the
     * address isn't filled in, so continue with unknown */
    fprintf(stderr, "WARNING estats_connection_tuple_as_string has"
        " failed this could be due to using the 3.5 kernel patch which"
        " doesn't log this information!!!!");
    estats_error_print(stderr, err);
    estats_error_free(&err);
    sprintf(title, "unknown:unknown --> unknown");
    sprintf(remport, "unknown");
    // exit(EXIT_FAILURE);
  }

  sprintf(title, "%s:%s --> %s", tuple_ascii.local_addr,
                  tuple_ascii.local_port, tuple_ascii.rem_addr);
  sprintf(remport, "%s", tuple_ascii.rem_port);
  /* Notes the time fo this the first snap in the global start_time
   * because ElapsedTimeMicroSec is unimplemented in the kernel patch */
  start_time = snap->tv.sec * 1000000 + snap->tv.usec;

#endif
}
Пример #5
0
/**
 * Set Cwnd limit
 * @param connarg tcp_stat_connection pointer
 * @param group_arg tcp_stat group pointer
 * @param agentarg tcp_stat agent pointer
 * */
void setCwndlimit(tcp_stat_connection connarg, tcp_stat_group* grouparg,
                  tcp_stat_agent* agentarg, Options* optionsarg) {
#if USE_WEB100
    web100_var *LimRwin, *yar;
#elif USE_WEB10G
    struct estats_val yar;
#endif

    u_int32_t limrwin_val;

    if (optionsarg->limit > 0) {
        log_print(1, "Setting Cwnd limit - ");

#if USE_WEB100
        if (connarg != NULL) {
            log_println(1,
                        "Got web100 connection pointer for recvsfd socket\n");
            char yuff[32];
            web100_agent_find_var_and_group(agentarg, "CurMSS", &grouparg,
                                            &yar);
            web100_raw_read(yar, connarg, yuff);
            log_println(1, "MSS = %s, multiplication factor = %d",
                        web100_value_to_text(web100_get_var_type(yar), yuff),
                        optionsarg->limit);
            limrwin_val = optionsarg->limit
                          * (atoi(
                                 web100_value_to_text(web100_get_var_type(yar),
                                         yuff)));
            web100_agent_find_var_and_group(agentarg, "LimRwin", &grouparg,
                                            &LimRwin);
            log_print(1, "now write %d to limit the Receive window",
                      limrwin_val);
            web100_raw_write(LimRwin, connarg, &limrwin_val);
#elif USE_WEB10G
        if (connarg != -1) {
            log_println(1,
                        "Got web10g connection for recvsfd socket\n");
            web10g_get_val(agentarg, connarg, "CurMSS", &yar);
            log_println(1, "MSS = %s, multiplication factor = %d",
                        yar.uv32, optionsarg->limit);
            limrwin_val = optionsarg->limit * yar.uv32;
            log_print(1, "now write %d to limit the Receive window", limrwin_val);
            estats_write_var("LimRwin", limrwin_val, connarg, agentarg);
#endif
            log_println(1, "  ---  Done");
        }
    }
}

/**
 * Check if receiver is clogged and use decision to temporarily
 * stop sending packets.
 * @param nextseqtosend integer indicating the Next Sequence Number To Be Sent
 * @param lastunackedseq integer indicating the oldest un-acked sequence number
 * @return integer indicating whether buffer is clogged
 * */
int is_buffer_clogged(int nextseqtosend, int lastunackedseq) {
    int recclog = 0;
    if ((RECLTH << 2) < (nextseqtosend - lastunackedseq - 1)) {
        recclog = 1;
    }
    return recclog;
}