double network::gibbsSampling(int pos, int value, int t) { int size = nodes.size(); int sample[2][size]; srand((unsigned int) time(NULL)); //Forward Sampling topologicalSort(); for (int i = 0; i < size; i++) { int j = topOrder[i]; if (nodes.at(j).isObserved()) { sample[0][j] = nodes.at(j).getValue(); } else { sample[0][j] = (toss() <= (nodes.at(j).factor(1))); nodes.at(j).setValue(sample[0][j]); } } //GIBBS SAMPLING double sumMix = 0; double sum = 0; int mixSize = t*0.02; int mixStart = 0; for (int i = 1; i <= t; i++) { assign(sample[0]); for (int j = 0; j < 7; j++) { if ((*(nodeAt(j))).isObserved()) { sample[1][j] = sample[0][j]; } else { sample[1][j] = (toss() <= (pSamplingNode(j, 1))); (*(nodeAt(j))).setValue(sample[1][j]); } } //MIXING PROCESS if (i <= mixStart + mixSize) { sumMix += pSamplingNode(pos, value); } else { sum += pSamplingNode(pos, value); } if (i == mixStart + mixSize * 2) { if (abs(sumMix / mixSize - sum / mixSize) < 0.001) { sum += sumMix; }else{ sumMix = sum; sum = 0; mixStart += mixSize; } } //UPDATE OF PREVIOUS SAMPLE for (int j = 0; j < 7; j++) { sample[0][j] = sample[1][j]; } } return sum/(t-mixStart); }
lnklist* ll_create_(size_t szelem) { lnklist* ll = (lnklist*) malloc(sizeof(lnklist)); if(!ll) toss(MemoryError); ll->elem_size = szelem; ll->head = (lnklist_node*) malloc(sizeof(lnklist_node)); ll->tail = ll->head; ll->length = 0; // past-the-end node if(!ll->head) toss(MemoryError); ll->head->next = NULL; ll->head->prev = NULL; ll->head->data = NULL; return ll; }
graph* g_create_(size_t szelem, graph_type gt) { graph* g = (graph*)malloc(sizeof(graph)); if(!g) toss(MemoryFault); g->elem_size = szelem; g->nodes = ll_create(gnode); g->edges = ll_create(gedge); g->gtype = gt; return g; }
gnode* g_add_node(graph* g, void* data) { gnode n; n.data = (uint8_t*)malloc(g->elem_size); n.rsrv = NULL; if(!n.data) toss(MemoryFault); if(data) memcpy(n.data, data, g->elem_size); if(g->gtype == DIRECTED) { n.adj.directed.in = ll_create(gedge*); n.adj.directed.out = ll_create(gedge*); } else if(g->gtype == UNDIRECTED) {
void Mutation(int **Local_p,float muta_rate){ // Pass through the max_pop , flip if it will mutation or not int i,status; for(i = 0; i<max_pop;i++){ status = toss(i,muta_rate); if(status == 1){ // muta occur int temp = Local_p[i][city_number/3] ; Local_p[i][city_number/3] = Local_p[i][city_number/4]; Local_p[i][city_number/4] = temp; } } }
void Crossover(int **Local_p,int *weight,float cross_rate){ // choosing the center : (city_number / 2) to (3*city_number / 4) to do crossover // choosing 2 for a pair , if chosen , store to the temp(next generation) , if not , store those parent into next generation int i,j,k,status,parent1,parent2,average; int **temp_pop = allocate_dimension(max_pop , city_number); int temp_index = 0,now_index=0; /* When Temp_index = max_pop => End */ /* First , get the average weight */ for(i=0;i<max_pop;i++){ average += weight[i]; } average = average / max_pop; while(1){ // Step 1 : Select 2 parent ( from Local_p ) , by pop_weight , more small more better /* Second , Select the weight < average 's population*/ parent1 = Select_parent(weight,now_index,average); now_index = parent1+1; parent2 = Select_parent(weight,now_index,average); now_index = parent2+1; //printf("Average %d ; Parent1 is %d , Parent2 is %d\n",average,parent1,parent2); // Step 2 : Decide do or not do crossover status = toss(now_index,cross_rate); if(status == 1){ // do crossover and store into temp Implement_Crossover(Local_p,temp_pop,parent1,parent2,temp_index); temp_index += 2; } else{ // directly store the file into temp for(i=0;i<city_number;i++){ temp_pop[temp_index][i] = Local_p[parent1][i]; temp_pop[temp_index+1][i] = Local_p[parent2][i]; } temp_index += 2; } // temp_index += 2 , if temp_index > max_pop , then break. if(temp_index >= max_pop){ break; } } // switch matrix for(i = 0 ; i < max_pop ; i++){ for(j = 0 ; j < city_number ; j++){ Local_p[i][j] = temp_pop[i][j]; } } free(temp_pop); }
void ll_remove(lnklist* ll, ll_iter i) { if(ll_is_end(i)) toss(RemovingTail); if(!i->prev && ll->head == i) { // head ll->head = i->next; i->next->prev = NULL; } else { i->prev->next = i->next; i->next->prev = i->prev; } free(i); ll->length--; }
BTCACHERW2::~BTCACHERW2() { commit(); toss(); delete [] nodes; nodes = 0; delete [] header; header = 0; header_modified = false; delete [] idx; idx = 0; delete [] modified; modified = 0; max = 0; context = 0; node_size = 0; header_size = 0; read = 0; write = 0; }
void ll_insert_bef(lnklist* ll, ll_iter cur, void* data) { lnklist_node* new_nd = (lnklist_node*) malloc(sizeof(lnklist_node) + ll->elem_size); if(!new_nd) toss(MemoryError); new_nd->data = (unsigned char*)(new_nd + 1); if(data) memcpy(new_nd->data, data, ll->elem_size); if(cur == ll->head) { new_nd->next = ll->head; new_nd->prev = NULL; ll->head->prev = new_nd; ll->head = new_nd; } else { new_nd->prev = cur->prev; new_nd->next = cur; cur->prev->next = new_nd; cur->prev = new_nd; } ll->length++; }
void control_xmit (void *b) { struct buffer *buf = (struct buffer *) b; struct tunnel *t; struct timeval tv; int ns; if (!buf) { l2tp_log (LOG_WARNING, "%s: called on NULL buffer!\n", __FUNCTION__); return; } ns = ntohs (((struct control_hdr *) (buf->start))->Ns); t = buf->tunnel; if (t) { #ifdef DEBUG_CONTROL_XMIT l2tp_log (LOG_DEBUG, "trying to send control packet %d to %d\n", ns, t->ourtid); #endif if (ns < t->cLr) { #ifdef DEBUG_CONTROL_XMIT l2tp_log (LOG_DEBUG, "%s: Tossing packet %d\n", __FUNCTION__, ns); #endif /* Okay, it's been received. Let's toss it now */ toss (buf); return; } } buf->retries++; if (buf->retries > DEFAULT_MAX_RETRIES) { /* * Too many retries. Either kill the tunnel, or * if there is no tunnel, just stop retransmitting. */ if (t) { if (t->self->needclose) { l2tp_log (LOG_DEBUG, "Unable to deliver closing message for tunnel %d. Destroying anyway.\n", t->ourtid); t->self->needclose = 0; t->self->closing = -1; tv.tv_sec = 1; tv.tv_usec = 0; schedule (tv, foo, t); } else { l2tp_log (LOG_NOTICE, "Maximum retries exceeded for tunnel %d. Closing.\n", t->ourtid); strcpy (t->self->errormsg, "Timeout"); t->self->needclose = -1; tv.tv_sec = 1; tv.tv_usec = 0; schedule (tv, foo, t); } call_close(t->self); } toss (buf); } else { tv.tv_sec = 1; tv.tv_usec = 0; if (buf->retries > 1) { tv.tv_sec = (time_t)((buf->retries-1) * 2); if (tv.tv_sec > 8) tv.tv_sec = 8; } schedule (tv, control_xmit, buf); #ifdef DEBUG_CONTROL_XMIT l2tp_log (LOG_DEBUG, "%s: Scheduling and transmitting packet %d, retries: %d\n", __FUNCTION__, ns, buf->retries); #endif udp_xmit (buf, t); } }
ssize_t evilsendto (int sockfd, char *msg, size_t msgLen, int flags, struct sockaddr *toAddr, socklen_t addrLen) { sigset_t mask, oldmask; int bytesSent; DelayedSendArgsType *args; if (msgLen > MAX_MSG_LEN) { errno = EMSGSIZE; return -1; } sigemptyset(&mask); sigaddset(&mask, SIGALRM); sigaddset(&mask, SIGIO); if (pthread_sigmask(SIG_BLOCK, &mask, &oldmask) < 0) { fprintf(stderr, "Error: %d in evil send: sigmask.\n", errno); exit(0); }; if (toss(crptProb)) { int randomByte = (rand() % msgLen); printf("\nmsg before corrupion: %s",msg); printf("\ncorrupted:%c",msg[randomByte]); msg[randomByte] = ~msg[randomByte]; printf("\nmsg after corrupion: %s",msg); PRINTDEBUG(printf("EVIL: corrupting message on %d.\n", sockfd)); bytesSent = sendto(sockfd, msg, msgLen, flags, toAddr, addrLen); msg[randomByte] = ~msg[randomByte]; } else if (toss(dropProb)) { PRINTDEBUG(printf("EVIL: droping message on %d.\n", sockfd)); bytesSent = msgLen; } else if (toss(dupProb)) { struct timeval delay; int milliDelay; milliDelay = minDelay + rand()%(maxDelay-minDelay+1); delay.tv_sec = milliDelay/1000; delay.tv_usec = 1000 * (milliDelay%1000); PRINTDEBUG(printf("EVIL: duplicating message on %d.\n", sockfd)); if (milliDelay > 0) { args = makeDelayedSendArgs(sockfd, msg, msgLen, flags, toAddr, addrLen); if (setEvent(delay, delayedSend, args, sizeof(*args)) < 0) { fprintf(stderr, "Error: %d in evil send: setEvent.\n", errno); exit(0); } free(args); } else { bytesSent = sendto(sockfd, msg, msgLen, flags, toAddr, addrLen); } bytesSent = sendto(sockfd, msg, msgLen, flags, toAddr, addrLen); } else if (toss(delayProb)) { struct timeval delay; int milliDelay; milliDelay = minDelay + rand()%(maxDelay-minDelay+1); delay.tv_sec = milliDelay/1000; delay.tv_usec = 1000 * (milliDelay%1000); PRINTDEBUG(printf("EVIL: delaying message on %d.\n", sockfd)); if (milliDelay > 0) { args = makeDelayedSendArgs(sockfd, msg, msgLen, flags, toAddr, addrLen); if (setEvent(delay, delayedSend, args, sizeof(*args)) < 0) { fprintf(stderr, "Error: %d in evil send: setEvent.\n", errno); exit(0); } free(args); bytesSent = msgLen; } else { bytesSent = sendto(sockfd, msg, msgLen, flags, toAddr, addrLen); } } else { PRINTDEBUG(printf("EVIL: sending message on %d.\n", sockfd)); bytesSent = sendto(sockfd, msg, msgLen, flags, toAddr, addrLen); } if (pthread_sigmask(SIG_SETMASK, &oldmask, NULL) < 0) { fprintf(stderr, "Error: %d in evil send: sigmask.\n", errno); exit(0); }; return bytesSent; }
void call_close (struct call *c) { struct buffer *buf; struct schedule_entry *se, *ose; struct call *tmp, *tmp2; if (!c || !c->container) { l2tp_log (LOG_DEBUG, "%s: called on null call or containerless call\n", __FUNCTION__); return; } if (c == c->container->self) { /* * We're actually closing the * entire tunnel */ /* First deschedule any remaining packet transmissions for this tunnel. That means Hello's and any reminaing packets scheduled for transmission. This is a very nasty little piece of code here. */ se = events; ose = NULL; while (se) { if ((((struct buffer *) se->data)->tunnel == c->container) || ((struct tunnel *) se->data == c->container)) { #ifdef DEBUG_CLOSE l2tp_log (LOG_DEBUG, "%s: Descheduling event\n", __FUNCTION__); #endif if (ose) { ose->next = se->next; if ((struct tunnel *) se->data != c->container) toss ((struct buffer *) (se->data)); free (se); se = ose->next; } else { events = se->next; if ((struct tunnel *) se->data != c->container) toss ((struct buffer *) (se->data)); free (se); se = events; } } else { ose = se; se = se->next; } } if (c->closing) { /* Really close this tunnel, as our StopCCN has been ack'd */ #ifdef DEBUG_CLOSE l2tp_log (LOG_DEBUG, "%s: Actually closing tunnel %d\n", __FUNCTION__, c->container->ourtid); #endif #ifdef USE_KERNEL if (kernel_support) ioctl (server_socket, L2TPIOCDELTUNNEL, c->container->ourtid); #endif destroy_tunnel (c->container); return; } /* * We need to close, but need to provide reliable delivery * of the final StopCCN. We record our state to know when * we have actually received an ACK on our StopCCN */ c->closeSs = c->container->control_seq_num; buf = new_outgoing (c->container); add_message_type_avp (buf, StopCCN); if (c->container->hbit) { mk_challenge (c->container->chal_them.vector, VECTOR_SIZE); add_randvect_avp (buf, c->container->chal_them.vector, VECTOR_SIZE); } add_tunnelid_avp (buf, c->container->ourtid); if (c->result < 0) c->result = RESULT_CLEAR; if (c->error < 0) c->error = 0; add_result_code_avp (buf, c->result, c->error, c->errormsg, strlen (c->errormsg)); add_control_hdr (c->container, c, buf); if (packet_dump) do_packet_dump (buf); #ifdef DEBUG_CLOSE l2tp_log (LOG_DEBUG, "%s: enqueing close message for tunnel\n", __FUNCTION__); #endif control_xmit (buf); /* * We also need to stop all traffic on any calls contained * within us. */ tmp = c->container->call_head; while (tmp) { tmp2 = tmp->next; tmp->needclose = 0; tmp->closing = -1; call_close (tmp); tmp = tmp2; } /* mf, 16.04.2003: change log message to show tunneltag */ // l2tp_log (LOG_LOG, // "%s : Connection %d closed to %s, port %d (%s)\n", __FUNCTION__, // c->container->tid, // IPADDY (c->container->peer.sin_addr), // ntohs (c->container->peer.sin_port), c->errormsg); l2tp_log (LOG_LOG, "%s : Connection closed with peer %s, reason: %s\n", __FUNCTION__, c->container->tunneltag, c->errormsg); } else { /* * Just close a call */ #ifdef USE_KERNEL struct l2tp_call_opts co; #endif if (c->zlb_xmit) deschedule (c->zlb_xmit); /* if (c->dethrottle) deschedule(c->dethrottle); */ if (c->closing) { #ifdef DEBUG_CLOSE l2tp_log (LOG_DEBUG, "%s: Actually closing call %d\n", __FUNCTION__, c->ourcid); #endif destroy_call (c); return; } #ifdef USE_KERNEL if (kernel_support) { co.ourtid = c->container->ourtid; co.ourcid = c->ourcid; ioctl (server_socket, L2TPIOCGETCALLOPTS, &co); co.flags = co.flags & ~L2TP_FLAG_CALL_UP; ioctl (server_socket, L2TPIOCSETCALLOPTS, &co); } #endif c->closeSs = c->container->control_seq_num; buf = new_outgoing (c->container); add_message_type_avp (buf, CDN); if (c->container->hbit) { mk_challenge (c->container->chal_them.vector, VECTOR_SIZE); add_randvect_avp (buf, c->container->chal_them.vector, VECTOR_SIZE); } if (c->result < 0) c->result = RESULT_CLEAR; if (c->error < 0) c->error = 0; add_result_code_avp (buf, c->result, c->error, c->errormsg, strlen (c->errormsg)); #ifdef TEST_HIDDEN add_callid_avp (buf, c->ourcid, c->container); #else add_callid_avp (buf, c->ourcid); #endif add_control_hdr (c->container, c, buf); if (packet_dump) do_packet_dump (buf); #ifdef DEBUG_CLOSE l2tp_log (LOG_DEBUG, "%s: enqueuing close message for call %d\n", __FUNCTION__, c->ourcid); #endif control_xmit (buf); l2tp_log (LOG_LOG, "%s: Call %d to %s disconnected\n", __FUNCTION__, c->ourcid, IPADDY (c->container->peer.sin_addr)); } /* * Note that we're in the process of closing now */ c->closing = -1; }
Coin::Coin() { srand(time(0)); toss(); }
void control_xmit (void *b) { struct buffer *buf = (struct buffer *) b; struct tunnel *t; struct timeval tv; int ns; if (!buf) { log (LOG_WARN, "%s: called on NULL buffer!\n", __FUNCTION__); return; } buf->retries++; t = buf->tunnel; ns = ntohs (((struct control_hdr *) (buf->start))->Ns); if (t) { if (ns < t->cLr) { #ifdef DEBUG_CONTROL_XMIT log (LOG_DEBUG, "%s: Tossing packet %d\n", __FUNCTION__, ns); #endif /* Okay, it's been received. Let's toss it now */ toss (buf); return; } } if (buf->retries > DEFAULT_MAX_RETRIES) { /* * Too many retries. Either kill the tunnel, or * if there is no tunnel, just stop retransmitting. */ if (t) { if (t->self->needclose) { log (LOG_DEBUG, "%s: Unable to deliver closing message for tunnel %d. Destroying anyway.\n", __FUNCTION__, t->ourtid); t->self->needclose = 0; t->self->closing = -1; /* , added by MJ., for terminate program when time out. */ extern void death_handler (int signal); death_handler(SIGTERM); /* add end, by MJ.*/ } else { log (LOG_DEBUG, "%s: Maximum retries exceeded for tunnel %d. Closing.\n", __FUNCTION__, t->ourtid); strcpy (t->self->errormsg, "Timeout"); t->self->needclose = -1; } } } else { /* * FIXME: How about adaptive timeouts? */ tv.tv_sec = 1; tv.tv_usec = 0; schedule (tv, control_xmit, buf); #ifdef DEBUG_CONTROL_XMIT log (LOG_DEBUG, "%s: Scheduling and transmitting packet %d\n", __FUNCTION__, ns); #endif udp_xmit (buf); } }
/* read gjf Cartesian file. */ void read_gjf_cartesian(char *file, structGraphic *g) { FILE *fp; int flag; int i, k, nedge; int ncount, key[20]; decimal value[20]; char line[300], name[15]; flag = 0; i = k = 0; nedge = 0; init_graphic(g); fp = fopen(file, "r"); JmpOrNot(fp, '%'); JmpOrNot(fp, '#'); JmpSpace(fp); toss(fp, 3); while(fgets(line, sizeof(line), fp) != NULL) { if(is_blank_line(line)) break; else { sscanf(line, "%s", name); g->vex[i].id = i+1; strcpy(g->vex[i].element_name, name); //printf("%s\n", name); i++; } } g->n = i; while(fgets(line, sizeof(line), fp) != NULL) { if(is_blank_line(line)) break; ncount = count_tokens(ltrim(line), " "); //printf("%d\n\n", ncount); nedge += ncount/2; k = 0; for(i = 0; i < ncount; i++) { if(i == 0 || i%2 == 1) key[k++] = atoi(gettoken(line," ",i+1)); else value[0] = (decimal)atof(gettoken(line," ",i+1)); } //g->edge[key[0]-1][key[0]-1] = INFINITY; //printf("%d\n", k); for(i = 1; i < k; i++) { g->edge[key[0]-1][key[i]-1] = 1; g->edge[key[i]-1][key[0]-1] = 1; } } g->e = nedge; //printf("%d\n", nedge); if(read_gjf_match_ff(file, "match", g) != g->n) { printf("ERROR OCCURED... FILE:%s LINE:%s\n", __FILE__, __LINE__); exit(1); } return; }
/* Add a face with the given vertices */ void add_face(int a, int b, int c) { if (faces.len == faces.capacity) { /* Double size when we run out... */ faces.capacity *= 2; faces.nodes = (face_t **)realloc(faces.nodes, sizeof(face_t *) * faces.capacity); } if (vertices.len < a || vertices.len < b || vertices.len < c) { /* Frick... */ fprintf(stderr, "ERROR: Haven't yet collected enough vertices for the face %d %d %d (have %d)!\n", a, b, c, vertices.len); exit(1); } /* Create a new triangle */ faces.nodes[faces.len] = malloc(sizeof(face_t)); faces.nodes[faces.len]->a = vertices.nodes[a-1]; faces.nodes[faces.len]->b = vertices.nodes[b-1]; faces.nodes[faces.len]->c = vertices.nodes[c-1]; /* Calculate some normals */ vertex_t u = {.x = faces.nodes[faces.len]->b->x - faces.nodes[faces.len]->a->x, .y = faces.nodes[faces.len]->b->y - faces.nodes[faces.len]->a->y, .z = faces.nodes[faces.len]->b->z - faces.nodes[faces.len]->a->z}; vertex_t v = {.x = faces.nodes[faces.len]->c->x - faces.nodes[faces.len]->a->x, .y = faces.nodes[faces.len]->c->y - faces.nodes[faces.len]->a->y, .z = faces.nodes[faces.len]->c->z - faces.nodes[faces.len]->a->z}; /* Set the face normals */ faces.nodes[faces.len]->normal.x = ((u.y * v.z) - (u.z * v.y)); faces.nodes[faces.len]->normal.y = -((u.z * v.x) - (u.x * v.z)); faces.nodes[faces.len]->normal.z = ((u.x * v.y) - (u.y * v.x)); faces.len++; } void finish_normals() { /* Loop through vertices and accumulate normals for them */ for (uint32_t i = 0; i < faces.len; ++i) { /* Vertex a */ faces.nodes[i]->a->normal.x += faces.nodes[i]->normal.x; faces.nodes[i]->a->normal.y += faces.nodes[i]->normal.y; faces.nodes[i]->a->normal.z += faces.nodes[i]->normal.z; /* Vertex b */ faces.nodes[i]->b->normal.x += faces.nodes[i]->normal.x; faces.nodes[i]->b->normal.y += faces.nodes[i]->normal.y; faces.nodes[i]->b->normal.z += faces.nodes[i]->normal.z; /* Vertex c */ faces.nodes[i]->c->normal.x += faces.nodes[i]->normal.x; faces.nodes[i]->c->normal.y += faces.nodes[i]->normal.y; faces.nodes[i]->c->normal.z += faces.nodes[i]->normal.z; } } /* Discard the rest of this line */ void toss(FILE * f) { while (fgetc(f) != '\n'); } /* Load a Wavefront Obj model */ void load_wavefront(char * filename) { /* Open the file */ FILE * obj = fopen(filename, "r"); int collected = 0; char d = ' '; /* Initialize the lists */ init_model(); while (!feof(obj)) { /* Scan in a line */ collected = fscanf(obj, "%c ", &d); if (collected == 0) continue; switch (d) { case 'v': { /* Vertex */ float x, y, z; collected = fscanf(obj, "%f %f %f\n", &x, &y, &z); if (collected < 3) fprintf(stderr, "ERROR: Only collected %d points!\n", collected); add_vertex(x, y, z); } break; case 'f': { /* Face */ int a, b, c; collected = fscanf(obj, "%d %d %d\n", &a, &b, &c); if (collected < 3) fprintf(stderr, "ERROR: Only collected %d vertices!\n", collected); add_face(a,b,c); } break; default: /* Something else that we don't care about */ toss(obj); break; } } /* Finalize the vertex normals */ finish_normals(); fclose(obj); } /* Vertex, fragment, program */ GLuint v, f, p; /* Read a file into a buffer and return a pointer to the buffer */ char * readFile(char * filename, int32_t * size) { FILE * tex; char * texture; tex = fopen(filename, "r"); fseek(tex, 0L, SEEK_END); *size = ftell(tex); texture = malloc(*size); fseek(tex, 0L, SEEK_SET); fread(texture, *size, 1, tex); fclose(tex); return texture; }
void control_xmit (void *b) { struct buffer *buf = (struct buffer *) b; struct tunnel *t; struct timeval tv; int ns; //RY: start here /* if(xxx == IPv6) { control_xmit_ipv6(b); return; } */ //RY: ends here if (!buf) { l2tp_log (LOG_WARNING, "%s: called on NULL buffer!\n", __FUNCTION__); return; } t = buf->tunnel; #ifdef DEBUG_CONTROL_XMIT if(t) { l2tp_log (LOG_DEBUG, "trying to send control packet to %d\n", t->ourtid); } #endif buf->retries++; ns = ntohs (((struct control_hdr *) (buf->start))->Ns); if (t) { if (ns < t->cLr) { #ifdef DEBUG_CONTROL_XMIT l2tp_log (LOG_DEBUG, "%s: Tossing packet %d\n", __FUNCTION__, ns); #endif /* Okay, it's been received. Let's toss it now */ toss (buf); return; } } if (buf->retries > DEFAULT_MAX_RETRIES) { /* * Too many retries. Either kill the tunnel, or * if there is no tunnel, just stop retransmitting. */ if (t) { if (t->self->needclose) { l2tp_log (LOG_DEBUG, "Unable to deliver closing message for tunnel %d. Destroying anyway.\n", t->ourtid); t->self->needclose = 0; t->self->closing = -1; } else { l2tp_log (LOG_NOTICE, "Maximum retries exceeded for tunnel %d. Closing.\n", t->ourtid); strcpy (t->self->errormsg, "Timeout"); t->self->needclose = -1; } } free(buf->rstart); free(buf); } else { /* * FIXME: How about adaptive timeouts? */ tv.tv_sec = 1; tv.tv_usec = 0; schedule (tv, control_xmit, buf); #ifdef DEBUG_CONTROL_XMIT l2tp_log (LOG_DEBUG, "%s: Scheduling and transmitting packet %d\n", __FUNCTION__, ns); #endif udp_xmit (buf, t); } }
void call_close (struct call *c) { struct buffer *buf; struct schedule_entry *se, *ose; struct call *tmp, *tmp2; if (!c || !c->container) { l2tp_log (LOG_DEBUG, "%s: called on null call or containerless call\n", __FUNCTION__); return; } if (c == c->container->self) { /* * We're actually closing the * entire tunnel */ /* First deschedule any remaining packet transmissions for this tunnel. That means Hello's and any reminaing packets scheduled for transmission. This is a very nasty little piece of code here. */ se = events; ose = NULL; while (se) { if ((((struct buffer *) se->data)->tunnel == c->container) || ((struct tunnel *) se->data == c->container)) { #ifdef DEBUG_CLOSE l2tp_log (LOG_DEBUG, "%s: Descheduling event\n", __FUNCTION__); #endif if (ose) { ose->next = se->next; if ((struct tunnel *) se->data != c->container) toss ((struct buffer *) (se->data)); free (se); se = ose->next; } else { events = se->next; if ((struct tunnel *) se->data != c->container) toss ((struct buffer *) (se->data)); free (se); se = events; } } else { ose = se; se = se->next; } } if (c->closing) { /* Really close this tunnel, as our StopCCN has been ack'd */ #ifdef DEBUG_CLOSE l2tp_log (LOG_DEBUG, "%s: Actually closing tunnel %d\n", __FUNCTION__, c->container->ourtid); #endif destroy_tunnel (c->container); return; } /* * We need to close, but need to provide reliable delivery * of the final StopCCN. We record our state to know when * we have actually received an ACK on our StopCCN */ c->closeSs = c->container->control_seq_num; buf = new_outgoing (c->container); add_message_type_avp (buf, StopCCN); if (c->container->hbit) { mk_challenge (c->container->chal_them.vector, VECTOR_SIZE); add_randvect_avp (buf, c->container->chal_them.vector, VECTOR_SIZE); } add_tunnelid_avp (buf, c->container->ourtid); if (c->result < 0) c->result = RESULT_CLEAR; if (c->error < 0) c->error = 0; add_result_code_avp (buf, c->result, c->error, c->errormsg, strlen (c->errormsg)); add_control_hdr (c->container, c, buf); if (gconfig.packet_dump) do_packet_dump (buf); #ifdef DEBUG_CLOSE l2tp_log (LOG_DEBUG, "%s: enqueing close message for tunnel\n", __FUNCTION__); #endif control_xmit (buf); /* * We also need to stop all traffic on any calls contained * within us. */ tmp = c->container->call_head; while (tmp) { tmp2 = tmp->next; tmp->needclose = 0; tmp->closing = -1; call_close (tmp); tmp = tmp2; } l2tp_log (LOG_DEBUG, "Connection %d closed to %s, port %d (%s)\n", c->container->tid, IPADDY (c->container->peer.sin_addr), ntohs (c->container->peer.sin_port), c->errormsg); if(strcmp(c->errormsg,"Server closing") ) { if(!strcmp(c->errormsg,"goodbye!") ) l2tp_log (LOG_INFO, "Terminated by router connect %s, cause manual disconnect.\n", IPADDY (c->container->peer.sin_addr) ); else if( c->msgtype <= 0 || c->msgtype > 16 ) l2tp_log (LOG_INFO, "Detect %s from %s, port %d \n", c->errormsg, IPADDY (c->container->peer.sin_addr), ntohs (c->container->peer.sin_port)); else l2tp_log (LOG_INFO, "Detect %s %s from %s, port %d \n", msgtypes[c->msgtype],c->errormsg, IPADDY (c->container->peer.sin_addr), ntohs (c->container->peer.sin_port)); } //if( (!strcmp(c->errormsg, "Timeout")) && (c->container->tid != 0) ) // l2tp_log(LOG_INFO, "Terminated by router, cause no response to echo-requests."); } else { /* * Just close a call */ if (c->zlb_xmit) deschedule (c->zlb_xmit); /* if (c->dethrottle) deschedule(c->dethrottle); */ if (c->closing) { #ifdef DEBUG_CLOSE l2tp_log (LOG_DEBUG, "%s: Actually closing call %d\n", __FUNCTION__, c->ourcid); #endif destroy_call (c); return; } c->closeSs = c->container->control_seq_num; buf = new_outgoing (c->container); add_message_type_avp (buf, CDN); if (c->container->hbit) { mk_challenge (c->container->chal_them.vector, VECTOR_SIZE); add_randvect_avp (buf, c->container->chal_them.vector, VECTOR_SIZE); } if (c->result < 0) c->result = RESULT_CLEAR; if (c->error < 0) c->error = 0; add_result_code_avp (buf, c->result, c->error, c->errormsg, strlen (c->errormsg)); #ifdef TEST_HIDDEN add_callid_avp (buf, c->ourcid, c->container); #else add_callid_avp (buf, c->ourcid); #endif add_control_hdr (c->container, c, buf); if (gconfig.packet_dump) do_packet_dump (buf); #ifdef DEBUG_CLOSE l2tp_log (LOG_DEBUG, "%s: enqueuing close message for call %d\n", __FUNCTION__, c->ourcid); #endif control_xmit (buf); l2tp_log (LOG_DEBUG, "%s: Call %d to %s disconnected\n", __FUNCTION__, c->ourcid, IPADDY (c->container->peer.sin_addr)); } /* * Note that we're in the process of closing now */ c->closing = -1; }
void control_xmit (void *b) { struct buffer *buf = (struct buffer *) b; struct tunnel *t; struct timeval tv; int ns; #if defined(FOR_KEEP_ALIVE) unsigned long tmp_rx; unsigned long tmp_tx; #endif if (!buf) { log (LOG_WARN, "%s: called on NULL buffer!\n", __FUNCTION__); return; } buf->retries++; t = buf->tunnel; ns = ntohs (((struct control_hdr *) (buf->start))->Ns); #if defined(FOR_KEEP_ALIVE) tmp_rx = buf->received; tmp_tx = buf->transmitted; buf->send_count--; get_ppp_pktnr(0, buf); if (tmp_rx == 0) buf->receiving = 0; else { buf->receiving = buf->received -tmp_rx; } if (tmp_tx == 0) buf->transmitting = 0; else { buf->transmitting = buf->transmitted - tmp_tx; } if (buf->send_count > 0) { if (buf->receiving > 30 || buf->transmitting > 30) { if (buf->retries) buf->retries=1; } } #endif if (t) { if (ns < t->cLr) { #ifdef DEBUG_CONTROL_XMIT log (LOG_DEBUG, "%s: Tossing packet %d\n", __FUNCTION__, ns); #endif /* Okay, it's been received. Let's toss it now */ toss (buf); return; } } if (buf->retries > DEFAULT_MAX_RETRIES) { /* * Too many retries. Either kill the tunnel, or * if there is no tunnel, just stop retransmitting. */ if (t) { if (t->self->needclose) { log (LOG_DEBUG, "Unable to deliver closing message for tunnel %d. Destroying anyway.\n", t->ourtid); t->self->needclose = 0; t->self->closing = -1; } else { log (LOG_NOTICE, "Maximum retries exceeded for tunnel %d. Closing.\n", t->ourtid); strcpy (t->self->errormsg, "Timeout"); t->self->needclose = -1; } } free(buf->rstart); free(buf); } else { /* * FIXME: How about adaptive timeouts? */ tv.tv_sec = 1; tv.tv_usec = 0; schedule (tv, control_xmit, buf); #ifdef DEBUG_CONTROL_XMIT log (LOG_DEBUG, "%s: Scheduling and transmitting packet %d\n", __FUNCTION__, ns); #endif udp_xmit (buf); } }
int main(int argc, char **argv) { struct ODRmsg *msg; struct hwa_info *hwa, *hwahead; struct sockaddr_un su; struct sockaddr temp; struct sockaddr_un sckadr; struct sockaddr *sa; socklen_t addrlen; int i, j; int protocol, maxfdp1; fd_set rset; //char address[16]; char rcvline[MAXLINE]; struct hostent *host; if(argc < 2) { printf("Usage: odr staleness\n"); return -1; } staleness = atoi(argv[1]); gethostname(name, 16); host = malloc(sizeof(struct hostent)); host = gethostbyname(name); if(host == NULL) printf("host is NULL\n"); strncpy(canonical, inet_ntoa( *( struct in_addr*)( host -> h_addr_list[0])), 16); printf("Local ODR on host %s\n", name); printf( "Canonical IP: %s\n", canonical); printf("Finding interfaces\n"); for (i = 0, hwahead = hwa = Get_hw_addrs(); hwa != NULL && i < MAX_INTERFACES; hwa = hwa->hwa_next, i++) { if(strncmp(hwa->if_name, "eth0", 4) != 0 && strncmp(hwa->if_name, "lo", 2) != 0) { /* for(j = 0; j < 6; j++) { interfaces[i].if_haddr[j] = hwa->if_haddr[j]; }*/ memcpy((void*)interfaces[i].if_haddr, (void*)hwa->if_haddr, 6); interfaces[i].if_index = hwa->if_index; sa = hwa->ip_addr; strncpy(interfaces[i].ip_addr, sock_ntop_host(sa, sizeof(*sa)), 16); printf("IP Address: %s\n", interfaces[i].ip_addr); printf("Hardware Address: "); printHW(interfaces[i].if_haddr); printf("\nIndex: %d\n\n", interfaces[i].if_index); } else i--; } if_nums = i; err_msg("%s",ODR_SUNPATH); printf("Found %d interfaces\n", if_nums); //Creating packet socket pfsock = socket(AF_PACKET, SOCK_RAW, htons(ODR_PROTOCOL)); if(pfsock < 0) { printf("pfsock: %d %s\n", errno, strerror(errno)); return -1; } unlink(ODR_SUNPATH); bzero(&su, sizeof(su)); su.sun_family = AF_LOCAL; strcpy(su.sun_path, ODR_SUNPATH); //strcat(su.sun_path, "\0"); appsock = socket(AF_LOCAL, SOCK_DGRAM, 0); if(appsock < 0) { printf("appsock: %d %s\n", errno, strerror(errno)); return -1; } if(bind(appsock, (struct sockaddr*) &su, sizeof(su)) < 0) { printf("bind failed: %d %s\n", errno, strerror(errno)); return -1; } FD_ZERO(&rset); printf("Bound appsock\n"); for ( ; ; ) { FD_SET(pfsock, &rset); FD_SET(appsock, &rset); maxfdp1 = max(pfsock, appsock) + 1; printf("Selecting...\n"); if(select(maxfdp1, &rset, NULL, NULL, NULL) < 0) { printf("select error: %d %s\n", errno, strerror(errno)); } if(FD_ISSET(appsock, &rset)) { printf("appsock is ready\n"); //msg_recv(appsock, message, address, port); addrlen = sizeof(sckadr); if(recvfrom(appsock, rcvline, MAXLINE, 0, &temp, &addrlen) < 0) { printf("appsock recvfrom error: %d %s\n", errno, strerror(errno)); return -1; } //su = (struct sockaddr_un*) sa; //err_msg("%s",temp.sa_data); //err_msg("%d",addrlen); processAPPmsg(rcvline, &temp); } if(FD_ISSET(pfsock, &rset)) { printf("pfsock is ready\n"); if(recvfrom(pfsock, rcvline, MAXLINE, 0, sa, &addrlen) < 0) { printf("pfsock recvmsg error: %d %s\n", errno, strerror(errno)); return -1; } printf("Received message: \n"); printf("From: "); printHW(rcvline); printHW(rcvline + ETH_ALEN); if(!toss()) { msg = rcvline + 14; memcpy((void*)neighbor, (void*)rcvline + ETH_ALEN, ETH_ALEN); printf(" To: "); printHW(neighbor); printf("\n"); processODRmsg(msg, sa); } else printf("Toss it!\n"); } } }
void destroy_call (struct call *c) { /* * Here, we unconditionally destroy a call. */ struct call *p; struct timeval tv; pid_t pid; /* * Close the tty */ if (c->fd > 0) { close (c->fd); c->fd = -1; } /* if (c->dethrottle) deschedule(c->dethrottle); */ if (c->zlb_xmit) deschedule (c->zlb_xmit); toss(c->ppp_buf); #ifdef IP_ALLOCATION if (c->addr) unreserve_addr (c->addr); #endif /* * Kill off pppd and wait for it to * return to us. This should only be called * in rare cases if pppd hasn't already died * voluntarily */ pid = c->pppd; if (pid) { /* Set c->pppd to zero to prevent recursion with child_handler */ c->pppd = 0; /* * There is a bug in some pppd versions where sending a SIGTERM * does not actually seem to kill pppd, and xl2tpd waits indefinately * using waitpid, not accepting any new connections either. Therefor * we now use some more force and send it a SIGKILL instead of SIGTERM. * One confirmed buggy version of pppd is ppp-2.4.2-6.4.RHEL4 * See http://bugs.xelerance.com/view.php?id=739 * * Sometimes pppd takes 7 sec to go down! We don't have that much time, * since all other calls are suspended while doing this. */ #ifdef TRUST_PPPD_TO_DIE #ifdef DEBUG_PPPD l2tp_log (LOG_DEBUG, "Terminating pppd: sending TERM signal to pid %d\n", pid); #endif kill (pid, SIGTERM); #else #ifdef DEBUG_PPPD l2tp_log (LOG_DEBUG, "Terminating pppd: sending KILL signal to pid %d\n", pid); #endif kill (pid, SIGKILL); #endif } if (c->container) { p = c->container->call_head; /* * Remove us from the call list, although * we might not actually be there */ if (p) { if (p == c) { c->container->call_head = c->next; c->container->count--; } else { while (p->next && (p->next != c)) p = p->next; if (p->next) { p->next = c->next; c->container->count--; } } } } if (c->lac) { c->lac->c = NULL; if (c->lac->redial && (c->lac->rtimeout > 0) && !c->lac->rsched && c->lac->active) { #ifdef DEBUG_MAGIC l2tp_log (LOG_DEBUG, "Will redial in %d seconds\n", c->lac->rtimeout); #endif tv.tv_sec = c->lac->rtimeout; tv.tv_usec = 0; c->lac->rsched = schedule (tv, magic_lac_dial, c->lac); } } if(c->oldptyconf) free(c->oldptyconf); free (c); }