1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include "log.h"
#include "fifo.h"
#include "socklib.h"
#include "udpcast.h"
#include "rateGovernor.h"
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#endif
#if defined HAVE_DLSYM && defined NO_BB
#define DL_RATE_GOVERNOR
#endif
void *rgInitGovernor(struct net_config *cfg, struct rateGovernor_t *gov)
{
if(cfg->nrGovernors == MAX_GOVERNORS) {
fprintf(stderr, "Too many rate governors\n");
exit(1);
}
cfg->rateGovernor[cfg->nrGovernors] = gov;
return cfg->rateGovernorData[cfg->nrGovernors++] = gov->rgInitialize();
}
#ifdef DL_RATE_GOVERNOR
void rgParseRateGovernor(struct net_config *net_config, char *rg)
{
char *pos = strchr(rg, ':');
char *dlname;
char *params;
char *error;
void *rgdl;
struct rateGovernor_t *gov;
void *data;
if(pos) {
dlname = strndup(rg, pos-rg);
params = pos+1;
} else {
dlname = rg;
params = NULL;
}
rgdl = dlopen(dlname, RTLD_LAZY);
if(rgdl == NULL) {
fprintf(stderr, "Library load error %s\n", dlerror());
exit(1);
}
dlerror(); /* Clear any existing error */
gov = dlsym(rgdl, "governor");
if ((error = dlerror()) != NULL) {
fprintf(stderr, "Symbol resolve error: %s\n", error);
exit(1);
}
if(pos)
free(dlname);
data = rgInitGovernor(net_config, gov);
if(net_config->rateGovernorData == NULL) {
fprintf(stderr, "Rate governor initialization error\n");
exit(1);
}
if(gov->rgSetProp) {
while(params && *params) {
char *eqPos; /* Position of the equal sign */
const char *key; /* Property name */
const char *value; /* property value */
pos = strchr(params, ',');
if(pos == NULL)
pos = params + strlen(params);
eqPos = strchr(params, '=');
if(eqPos == NULL || eqPos >= pos) {
key = strndup(params, pos-params);
value = NULL;
} else {
key = strndup(params, eqPos-params);
value = strndup(eqPos+1, pos-(eqPos+1));
}
gov->rgSetProp(data, key, value);
if(*pos)
pos++;
params=pos;
}
}
if(gov->rgEndConfig) {
gov->rgEndConfig(data);
}
}
#endif
void rgWaitAll(struct net_config *cfg, int sock, in_addr_t ip, int size)
{
int i=0;
for(i=0; i<cfg->nrGovernors; i++) {
cfg->rateGovernor[i]->rgWait(cfg->rateGovernorData[i], sock, ip, size);
}
}
void rgShutdownAll(struct net_config *cfg)
{
int i=0;
for(i=0; i<cfg->nrGovernors; i++) {
if(cfg->rateGovernor[i]->rgShutdown)
cfg->rateGovernor[i]->rgShutdown(cfg->rateGovernorData[i]);
}
}
|