Beispiel #1
0
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);
	}
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
  }
}
Beispiel #4
0
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;
}
Beispiel #5
0
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);
}
Beispiel #6
0
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);
		}
	}
}
Beispiel #7
0
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);
}
Beispiel #8
0
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;
}
Beispiel #9
0
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--;
}
Beispiel #10
0
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--;
}
Beispiel #11
0
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;
}
Beispiel #12
0
/*
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);
  }
}
Beispiel #13
0
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;
}
Beispiel #14
0
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;
}