void processAck(rel_t* rel, struct ack_packet* ack_packet) { if (!rel) { return; } bool duplicate_acks = checkDupAck(rel, (int) ntohl(ack_packet->ackno)); int flag = 0; if(rel->c->sender_receiver != RECEIVER){ rel->recvWindows = (ntohl(ack_packet->rwnd)); if(ntohl(ack_packet->ackno) < 3 && rel->rtt == 0){ long int begin = (rel->rttTime.tv_sec * 1000) + (rel->rttTime.tv_usec / 1000); gettimeofday(&rel->rttTime, NULL); long int end = (rel->rttTime.tv_sec * 1000) + (rel->rttTime.tv_usec / 1000); rel->rtt = (end - begin) * 2; gettimeofday(&rel->rttTime, NULL); rel->rtt = 29; } } while (rel->senderBuff && ntohl(rel->senderBuff->packet->seqno) < ntohl(ack_packet->ackno)) { flag = 1; if (!duplicate_acks && (rel->cwndSize < rel->ssthresh)) { rel->cwndSize = rel->cwndSize + 1; } dequeue(&rel->senderBuff); } if (!duplicate_acks && (flag==1) && !(rel->cwndSize < rel->ssthresh)) { rel->cwndSize = rel->cwndSize + 1; } if (ntohl(ack_packet->ackno) > rel->seqLast) { //fprintf(stderr, "processAck done"); rel->noMoreAck = 1; rel_destroy(rel); } }
int rel_check_finished (rel_t *r) { assert(r); if (!r->read_eof || !r->printed_eof) { return 0; } /* Send window is [head of buffer queue, head of buffer queue + window size], * so we iterate over the send window, and check if there's anything in it that * we've sent (cause that would mean we haven't gotten an ack for that yet). */ int i = 0; for (i = bq_get_head_seq(r->send_bq); i <= bq_get_tail_seq(r->send_bq); i++) { /* If the element isn't buffered, we definately haven't sent it */ if (!bq_element_buffered(r->send_bq, i)) continue; /* Otherwise, we check the sent flag */ send_bq_element_t *elem = bq_get_element(r->send_bq, i); if (!elem->sent) { return 0; } } /* If we reach here, then we've received all acks for packets we sent, and * both other conditions are met. Destroy this rel_t. */ rel_destroy(r); return 1; }
void rel_timer () { /* Retransmit any packets that need to be retransmitted */ rel_t *r = rel_list; int i = 0; while (r != NULL) { rel_t *next = r->next; if (destroy_check(r) || r->destroy_wait>0) { r->destroy_wait++; if (r->destroy_wait > 2) { rel_destroy(r); continue; } } else { for (i=0; i < r->window_size; i++) { if (r->sendTimer[i] >= 5) { if (!check_pkt_acked(r, i)) { resend_pkt(r, i); } r->sendTimer[i] = 0; } else { r->sendTimer[i]++; } } } r = next; } }
bool processEOF(rel_t* rel) { if (rel && (rel->receiverBuff) && (rel->receiverBuff->packet)) { if (ntohs(rel->receiverBuff->packet->len) == 16) { rel->outputEOF = 1; conn_output(rel->c, NULL, 0); if (rel->c->sender_receiver == RECEIVER) { rel_destroy(rel); return true; } if (rel->pairEOFed && rel->inputEOF && rel->noMoreAck && rel->outputEOF) { fprintf(stderr, "rel_destroy\n"); rel_destroy(rel); } return true; } return false; } return false; }
void rel_read (rel_t *s) { int numPacketsInWindow = s->LAST_PACKET_SENT - s->LAST_PACKET_ACKED; fprintf(stderr, "REL_READ -- lastpacketsent: %d, lastacked: %d\n", s->LAST_PACKET_SENT, s->LAST_PACKET_ACKED); if (numPacketsInWindow == 0 && s->eofSent == 1 && s->eofRecv == 1) { rel_destroy(s); return; } if (numPacketsInWindow >= s->windowSize || s->eofSent) { // don't send, window's full, waiting for acks return; } // can send packet char payloadBuffer[MAX_PAYLOAD_SIZE]; int bytesReceived = conn_input(s->c, payloadBuffer, MAX_PAYLOAD_SIZE); if (bytesReceived == 0) { return; // no data is available at the moment, just return } else if (bytesReceived == -1) { // eof or error s->eofSent = 1; bytesReceived = 0; // Why do we need to create and send a packet here? // packet_t *packet = createDataPacket(s, payloadBuffer, bytesReceived); // conn_sendpkt(s->c, packet, HEADER_SIZE + bytesReceived); // free(packet); // return; } // TODO: Need to handle overflow bytes here as well packet_t *packet = createDataPacket(s, payloadBuffer, bytesReceived); s->LAST_PACKET_SENT++; fprintf(stderr, "Sent sequence number: %d\n", ntohl(packet->seqno)); conn_sendpkt(s->c, packet, HEADER_SIZE + bytesReceived); // Save packet until it's acked/in case it needs to be retransmitted int slot = s->LAST_PACKET_SENT - s->LAST_PACKET_ACKED - 1; // fprintf(stderr, "Slot: %d\n", slot); memcpy(s->sentPackets[slot]->packet, packet, HEADER_SIZE + bytesReceived); s->sentPackets[slot]->sentTime = getCurrentTime(); s->sentPackets[slot]->acked = 1; fprintf(stderr, "%s\n", "====================SENDING PACKET================"); // fprintf(stderr, "Packet data: %s\n", packet->data); free(packet); }
void checkEOFstatus(rel_t* rel){ if( rel->c->sender_receiver == RECEIVER ){ } else{ if (rel->inputEOF && rel->noMoreAck) { fprintf(stderr, "rel_destroy\n"); rel_destroy(rel); } } }
void rel_output (rel_t *r) { // printf("rel_output\n"); int numPacketsInWindow = r->LAST_PACKET_SENT - r->LAST_PACKET_ACKED; int i; // fprintf(stderr, "lastpacksent: %d, lackPackacked: %d\n", r->LAST_PACKET_SENT, r->LAST_PACKET_ACKED); for (i = 0; i < r->windowSize; i++) { // fprintf(stderr, "Recvpacket of %d has ack %d\n", i, r->recvPackets[i]->acked); if(r->recvPackets[i]->acked == 0) { break; } packet_t *pkt = r->recvPackets[i]->packet; uint16_t packet_len = ntohs(pkt->len); size_t len = conn_bufspace(r->c); // fprintf(stderr, "Packet len: %d\n", (int) packet_len); if(len >= packet_len - HEADER_SIZE) { if(packet_len == HEADER_SIZE) { r->eofRecv = 1; } // fprintf(stderr, "Outputting packet %d from recvPackets \n", i); conn_output(r->c, pkt->data, packet_len - HEADER_SIZE); r->recvPackets[i]->acked = 0; } else { break; } } // fprintf(stderr, "value of i: %d\n", i); // fprintf(stderr, "Next Packet Expected Before: %d\n", r->NEXT_PACKET_EXPECTED ); r->NEXT_PACKET_EXPECTED += i; struct ack_packet *ack = createAckPacket(r, r->NEXT_PACKET_EXPECTED); // fprintf(stderr, "Next Packet Expected: %d\n", r->NEXT_PACKET_EXPECTED); conn_sendpkt(r->c, (packet_t *)ack, ACK_PACKET_SIZE); free(ack); // fprintf(stderr, "reloutput -- numPackets: %d, eofRecv: %d, eofSend: %d\n", numPacketsInWindow, r->eofRecv, r->eofSent); if(numPacketsInWindow == 0 && r->eofRecv == 1 && r->eofSent == 1) { rel_destroy(r); return; } shiftRecvPacketList(r); }
static sql_rel * rewrite_replica( mvc *sql, sql_rel *rel, sql_table *t, sql_table *p) { node *n, *m; sql_rel *r = rel_basetable(sql, p, t->base.name); for (n = rel->exps->h, m = r->exps->h; n && m; n = n->next, m = m->next) { sql_exp *e = n->data; sql_exp *ne = m->data; exp_setname(sql->sa, ne, e->rname, e->name); } rel_destroy(rel); return r; }
void stack_pop_frame(mvc *sql) { while(!sql->vars[--sql->topvars].frame) { sql_var *v = &sql->vars[sql->topvars]; c_delete(v->name); VALclear(&v->value); v->value.vtype = 0; if (v->t && v->view) table_destroy(v->t); else if (v->rel) rel_destroy(v->rel); } if (sql->topvars && sql->vars[sql->topvars].name) c_delete(sql->vars[sql->topvars].name); sql->frame--; }
void stack_pop_frame(mvc *sql) { while(sql->vars[--sql->topvars].s) { sql_var *v = &sql->vars[sql->topvars]; _DELETE(v->name); VALclear(&v->value); v->value.vtype = 0; if (v->type.comp_type && v->view) table_destroy(v->type.comp_type); else if (v->s && v->view) rel_destroy(v->s); } if (sql->topvars && sql->vars[sql->topvars].name) _DELETE(sql->vars[sql->topvars].name); sql->frame--; }
void sendRead(rel_t *s){ if (s && s->inputEOF == 0) { int size = s->recvWindows; if(size > s->cwndSize){ size = s->cwndSize; } size = (size > 9) ? 9 : size; while (sizeOfQueue(s->senderBuff) < size) { packetQueue* tempPack = new_packet(); int dataIn = conn_input(s->c, tempPack->packet->data, 1000); if (dataIn == 0) { break; } if(dataIn > 0){ tempPack->packet->cksum = 0; tempPack->packet->len = htons((16 + dataIn)); tempPack->packet->seqno = htonl(s->seqOut); s->seqOut++; tempPack->packet->rwnd = htonl(s->recvWindows - sizeOfQueue(s->receiverBuff)); tempPack->packet->ackno = htonl(s->seqIn); tempPack->packet->cksum = cksum(tempPack->packet, (16 + dataIn)); addToQueue(&(s->senderBuff), tempPack); conn_sendpkt(s->c, tempPack->packet, (16 + dataIn)); } else{ s->inputEOF = 1; s->seqLast = s->seqOut; dataIn = 0; tempPack->packet->cksum = 0; tempPack->packet->len = htons((16 + dataIn)); tempPack->packet->seqno = htonl(s->seqOut); s->seqOut++; tempPack->packet->rwnd = htonl(s->recvWindows - sizeOfQueue(s->receiverBuff)); tempPack->packet->ackno = htonl(s->seqIn); tempPack->packet->cksum = cksum(tempPack->packet, (16 + dataIn)); addToQueue(&(s->senderBuff), tempPack); conn_sendpkt(s->c, tempPack->packet, (16 + dataIn)); } } return; } rel_destroy (s); return; }
/* If the reliable program is running in the receiver mode (see c.sender_receiver in rlib.c, you can get its value in rel_create), this receiver should send an EOF to the sender when rel_read is first called. After this first call, the function rel_read can simply return for later calls. Note that this EOF will wait in the receiver's sending window. When timeout happens, the receiver have to retransmit this EOF as well until an ACK is received. If the reliable is running in the sender mode, the rel_read's behavior is the same as that is described above in 3a. */ void rel_read (rel_t *s) { // printf("rel_read\n"); if(s->c->sender_receiver == RECEIVER) { // if already sent eof to the sender/not first call // return; if(s->eofSent == 1) { // fprintf(stderr, "%s\n", "EOF already sent in rel_read"); // s->eofSent = 0; return; } else { // first call // set eofSent to 1 s->eofSent = 1; // send eof char payloadBuffer[MAX_PAYLOAD_SIZE]; int bytesReceived = 0; packet_t *packet = createDataPacket(s, payloadBuffer, bytesReceived); conn_sendpkt(s->c, packet, HEADER_SIZE + bytesReceived); free(packet); // printf("Sending EOF to sender in rel_read\n"); } //if already sent EOF to the sender // return; //else // send EOF to the sender } else //run in the sender mode { //same logic as lab 1 int numPacketsInWindow = s->LAST_PACKET_SENT - s->LAST_PACKET_ACKED; // fprintf(stderr, "REL_READ -- lastpacketsent: %d, lastacked: %d\n", s->LAST_PACKET_SENT, s->LAST_PACKET_ACKED); // fprintf(stderr, "relread -- numPackets: %d, eofRecv: %d, eofSend: %d\n", numPacketsInWindow, s->eofRecv, s->eofSent); if (numPacketsInWindow == 0 && s->eofSent == 1 && s->eofRecv == 1) { rel_destroy(s); return; } if (numPacketsInWindow >= s->windowSize || s->eofSent) { // don't send, window's full, waiting for acks return; } // can send packet char payloadBuffer[MAX_PAYLOAD_SIZE]; memset(payloadBuffer, 0, MAX_PAYLOAD_SIZE); int bytesReceived = conn_input(s->c, payloadBuffer, MAX_PAYLOAD_SIZE); // fprintf(stderr, "Bytes received: %d\n", bytesReceived ); if (bytesReceived == 0) { return; // no data is available at the moment, just return } else if (bytesReceived == -1) { // eof or error s->eofSent = 1; bytesReceived = 0; // Why do we need to create and send a packet here? // packet_t *packet = createDataPacket(s, payloadBuffer, bytesReceived); // conn_sendpkt(s->c, packet, HEADER_SIZE + bytesReceived); // free(packet); // return; } // TODO: Need to handle overflow bytes here as well packet_t *packet = createDataPacket(s, payloadBuffer, bytesReceived); s->LAST_PACKET_SENT++; // fprintf(stderr, "Sent sequence number: %d\n", ntohl(packet->seqno)); // fprintf(stderr, "PACKET INFO: %s\n", packet->data); // fprintf(stderr, "PACKET INFO: %s\n", strdup(payloadBuffer)); // fprintf(stderr, "String Compare Value: %d\n", strcmp(packet->data, "")); conn_sendpkt(s->c, packet, HEADER_SIZE + bytesReceived); // Save packet until it's acked/in case it needs to be retransmitted int slot = s->LAST_PACKET_SENT - s->LAST_PACKET_ACKED - 1; // fprintf(stderr, "Slot: %d\n", slot); memcpy(s->sentPackets[slot]->packet, packet, HEADER_SIZE + bytesReceived); s->sentPackets[slot]->sentTime = getCurrentTime(); s->sentPackets[slot]->acked = 1; // fprintf(stderr, "%s\n", "====================SENDING PACKET================"); // fprintf(stderr, "Packet data: %s\n", packet->data); free(packet); } }
static sql_rel * distribute(mvc *sql, sql_rel *rel) { sql_rel *l = NULL, *r = NULL; prop *p, *pl, *pr; if (!rel) return rel; if (rel_is_ref(rel)) { if (has_remote_or_replica(rel)) { sql_rel *nrel = rel_copy(sql->sa, rel); if (nrel && rel->p) nrel->p = prop_copy(sql->sa, rel->p); rel_destroy(rel); rel = nrel; } else { return rel; } } switch (rel->op) { case op_basetable: { sql_table *t = rel->l; /* set_remote() */ if (isRemote(t)) { char *uri = t->query; p = rel->p = prop_create(sql->sa, PROP_REMOTE, rel->p); p->value = uri; } } case op_table: break; case op_join: case op_left: case op_right: case op_full: case op_apply: case op_semi: case op_anti: case op_union: case op_inter: case op_except: l = rel->l = distribute(sql, rel->l); r = rel->r = distribute(sql, rel->r); if (l && (pl = find_prop(l->p, PROP_REMOTE)) != NULL && r && (pr = find_prop(r->p, PROP_REMOTE)) == NULL) { r = rel->r = distribute(sql, replica(sql, rel->r, pl->value)); } else if (l && (pl = find_prop(l->p, PROP_REMOTE)) == NULL && r && (pr = find_prop(r->p, PROP_REMOTE)) != NULL) { l = rel->l = distribute(sql, replica(sql, rel->l, pr->value)); } if (l && (pl = find_prop(l->p, PROP_REMOTE)) != NULL && r && (pr = find_prop(r->p, PROP_REMOTE)) != NULL && strcmp(pl->value, pr->value) == 0) { l->p = prop_remove(l->p, pl); r->p = prop_remove(r->p, pr); pl->p = rel->p; rel->p = pl; } break; case op_project: case op_select: case op_groupby: case op_topn: case op_sample: rel->l = distribute(sql, rel->l); l = rel->l; if (l && (p = find_prop(l->p, PROP_REMOTE)) != NULL) { l->p = prop_remove(l->p, p); p->p = rel->p; rel->p = p; } break; case op_ddl: rel->l = distribute(sql, rel->l); if (rel->r) rel->r = distribute(sql, rel->r); break; case op_insert: case op_update: case op_delete: rel->r = distribute(sql, rel->r); break; } return rel; }
static sql_rel * replica(mvc *sql, sql_rel *rel, char *uri) { if (!rel) return rel; if (rel_is_ref(rel)) { if (has_remote_or_replica(rel)) { sql_rel *nrel = rel_copy(sql->sa, rel); if (nrel && rel->p) nrel->p = prop_copy(sql->sa, rel->p); rel_destroy(rel); rel = nrel; } else { return rel; } } switch (rel->op) { case op_basetable: { sql_table *t = rel->l; if (isReplicaTable(t)) { node *n; if (uri) { /* replace by the replica which matches the uri */ for (n = t->tables.set->h; n; n = n->next) { sql_table *p = n->data; if (isRemote(p) && strcmp(uri, p->query) == 0) { rel = rewrite_replica(sql, rel, t, p); break; } } } else { /* no match, use first */ sql_table *p = NULL; if (t->tables.set) { p = t->tables.set->h->data; rel = rewrite_replica(sql, rel, t, p); } else { rel = NULL; } } } } case op_table: break; case op_join: case op_left: case op_right: case op_full: case op_apply: case op_semi: case op_anti: case op_union: case op_inter: case op_except: rel->l = replica(sql, rel->l, uri); rel->r = replica(sql, rel->r, uri); break; case op_project: case op_select: case op_groupby: case op_topn: case op_sample: rel->l = replica(sql, rel->l, uri); break; case op_ddl: rel->l = replica(sql, rel->l, uri); if (rel->r) rel->r = replica(sql, rel->r, uri); break; case op_insert: case op_update: case op_delete: rel->r = replica(sql, rel->r, uri); break; } return rel; }