/* Compute and insert migration along directed edge (may fork child) */ static MIGRATION * create_migration(RBFNODE *from_rbf, RBFNODE *to_rbf) { const double end_thresh = 5e-6; PRICEMAT pmtx; MIGRATION *newmig; double *src_rem, *dst_rem; double total_rem = 1., move_amt; int i, j; /* check if exists already */ for (newmig = from_rbf->ejl; newmig != NULL; newmig = nextedge(from_rbf,newmig)) if (newmig->rbfv[1] == to_rbf) return(NULL); /* else allocate */ #ifdef DEBUG fprintf(stderr, "Building path from (theta,phi) (%.0f,%.0f) ", get_theta180(from_rbf->invec), get_phi360(from_rbf->invec)); fprintf(stderr, "to (%.0f,%.0f) with %d x %d matrix\n", get_theta180(to_rbf->invec), get_phi360(to_rbf->invec), from_rbf->nrbf, to_rbf->nrbf); #endif newmig = new_migration(from_rbf, to_rbf); if (run_subprocess()) return(newmig); /* child continues */ price_routes(&pmtx, from_rbf, to_rbf); src_rem = (double *)malloc(sizeof(double)*from_rbf->nrbf); dst_rem = (double *)malloc(sizeof(double)*to_rbf->nrbf); if ((src_rem == NULL) | (dst_rem == NULL)) { fprintf(stderr, "%s: Out of memory in create_migration()\n", progname); exit(1); } /* starting quantities */ memset(newmig->mtx, 0, sizeof(float)*from_rbf->nrbf*to_rbf->nrbf); for (i = from_rbf->nrbf; i--; ) src_rem[i] = rbf_volume(&from_rbf->rbfa[i]) / from_rbf->vtotal; for (j = to_rbf->nrbf; j--; ) dst_rem[j] = rbf_volume(&to_rbf->rbfa[j]) / to_rbf->vtotal; do { /* move a bit at a time */ move_amt = migration_step(newmig, src_rem, dst_rem, &pmtx); total_rem -= move_amt; } while ((total_rem > end_thresh) & (move_amt > 0)); for (i = from_rbf->nrbf; i--; ) { /* normalize final matrix */ double nf = rbf_volume(&from_rbf->rbfa[i]); if (nf <= FTINY) continue; nf = from_rbf->vtotal / nf; for (j = to_rbf->nrbf; j--; ) mtx_coef(newmig,i,j) *= nf; /* row now sums to 1.0 */ } end_subprocess(); /* exit here if subprocess */ free_routes(&pmtx); /* free working arrays */ free(src_rem); free(dst_rem); return(newmig); }
void free_options(struct if_options *ifo) { size_t i; if (ifo) { if (ifo->environ) { i = 0; while (ifo->environ[i]) free(ifo->environ[i++]); free(ifo->environ); } if (ifo->config) { i = 0; while (ifo->config[i]) free(ifo->config[i++]); free(ifo->config); } free_routes(ifo->routes); free(ifo->arping); free(ifo->blacklist); free(ifo->fallback); free(ifo); } }
static struct rt * decode_rfc3442_rt(int dl, const uint8_t *data) { const uint8_t *p = data; const uint8_t *e; uint8_t cidr; uint8_t ocets; struct rt *routes = NULL; struct rt *rt = NULL; /* Minimum is 5 -first is CIDR and a router length of 4 */ if (dl < 5) return NULL; e = p + dl; while (p < e) { cidr = *p++; if (cidr > 32) { free_routes(routes); errno = EINVAL; return NULL; } if (rt) { rt->next = xzalloc(sizeof(*rt)); rt = rt->next; } else { routes = rt = xzalloc(sizeof(*routes)); } rt->next = NULL; ocets = (cidr + 7) / 8; /* If we have ocets then we have a destination and netmask */ if (ocets > 0) { memcpy(&rt->dest.s_addr, p, (size_t)ocets); memset(&rt->net.s_addr, 255, (size_t)ocets - 1); memset((uint8_t *)&rt->net.s_addr + (ocets - 1), (256 - (1 << (32 - cidr) % 8)), 1); p += ocets; } else { rt->dest.s_addr = 0; rt->net.s_addr = 0; } /* Finally, snag the router */ memcpy(&rt->gate.s_addr, p, 4); p += 4; } return routes; }