Exemplo n.º 1
0
uint8_t bb_i2c_write( uint8_t addr, uint8_t *buf, uint8_t len )
{
    uint8_t rc = 0;

    bb_start();
    
    bb_out( addr );    // address + W
    if ( get_ack() )
    {
        while ( len > 0 )
        {
            bb_out( *buf++ );
            
            if ( get_ack() == 0 )
            {
                rc = 1;
                break;
            }
            
            len--;
        }
    }
    else 
    {
        rc = 1;
    }

    bb_stop();

    return rc;
}
Exemplo n.º 2
0
uint8_t bb_i2c_read( uint8_t addr, uint8_t *buf, uint8_t len )
{
    uint8_t rc = 0;
    
    bb_start();

    bb_out( addr | 0x01 ); // address + R
    if ( get_ack() )
    {
        while ( len > 0 )
        {
            *buf++ = bb_in();
                
            len--;
            if ( len > 0 )
            {
                send_ack();
            }
            else
            {
                send_nak();
            }
        }
    }
    else
    {
        rc = 1;
    }
    
    bb_stop();
    
    return rc;
}
Exemplo n.º 3
0
	void Handle (DHT& dht, const Host& host, const Packet& pckt)
	{
		Key k = pckt.GetArg<Key>(DHT_GET_KEY);
		pf_log[W_DHT] << "Get received with key " << k;

		if(dht.GetStorage()->hasKey(k))
		{
			pf_log[W_DHT] << "Answer with data " << dht.GetStorage()->getInfo(k)->GetStr();
			Packet get_ack(DHTGetAckType, dht.GetMe(), host.GetKey());
			get_ack.SetArg(DHT_GET_ACK_KEY, k);
			get_ack.SetArg(DHT_GET_ACK_DATA, dht.GetStorage()->getInfo(k));
			if(!dht.GetChimera()->Send(host, get_ack))
				pf_log[W_DHT] << "Send get ACK message failed!";
			return;
		}

		pf_log[W_DHT] << "Data not in cache, try to relay to a closest host.";
		if(!dht.GetChimera()->Route(pckt))
		{
			pf_log[W_DHT] << "I'm the owner and the key is unknow, answer with GET_NACK.";
			Packet get_nack(DHTGetNAckType, dht.GetMe(), host.GetKey());
			get_nack.SetArg(DHT_GET_NACK_KEY, k);
			if(!dht.GetChimera()->Send(host, get_nack))
				pf_log[W_DHT] << "Send get NACK message failed!";
			return;
		}
		pf_log[W_DHT] << "GET relayed.";
	}
Exemplo n.º 4
0
/**
 * handle packet loss case (timeout)
 * @param dl
 */
static void dl_loss(download_t *dl) {
    int i ;

    for (i = 0; i < LOSS_ACK_NUM; i++) {
        send_ack(dl->p_index, get_ack(dl));
    }
    dl->ts = get_timestamp_now();
    dl->block_update = 1;
}
Exemplo n.º 5
0
static int send_acked ( char *str )
{
    if ( scanfd < 0 )
	return -1;
    while ( *str ) {
	if ( write ( scanfd, str++, 1 ) != 1 || get_ack () < 0 )
	    return -1;
    }
    return 0;
}
Exemplo n.º 6
0
/*
 * jx100_reset
 *     Send a CAN character to the scanner to get it to reset.  This can
 *   be useful for aborting a scan.  One caveat is that the scanner
 *   resets its baud rate to 9600.
 *     It turns out that the scanner won't listen all of the time, and
 *   will even send some characters after being requested to reset.  Sigh.
 */
int jx100_reset ()
{
    if ( status )
	(*status) ( "resetting scanner" );
    scanlines = 0;
    if ( send ( "\x18" ) < 0 )		/* request a reset... */
	return -1;
    msleep ( 1000 );
    if ( send ( "\x18" ) < 0 )		/* ...and then request again */
	return -1;
    if ( cfgetispeed ( &tt ) != B9600 ) {		/* reset to 9600 */
	cfsetispeed ( &tt, B9600 );
	cfsetospeed ( &tt, B9600 );
	if ( tcsetattr ( scanfd, TCSANOW, &tt ) < 0 )
	    return -1;
#ifdef linux
	/* reset meaning of 38400 */
	(void) ioctl ( scanfd, TIOCGSERIAL, &serial );
	serial.flags &= ~ASYNC_SPD_MASK;
	(void) ioctl ( scanfd, TIOCSSERIAL, &serial );
#endif
    }
    /* we wait a bit, then discard any spurious characters that came in */
    msleep ( 1000 );
    if ( tcflush ( scanfd, TCIFLUSH ) < 0 )
	return -1;
    /* physical head movement during reset can take 3 - 10 seconds */
    timeout = 10000;
    if ( get_ack() == 0 )		/* got ack, good! */
	return 0;
    /* We didn't get an ack.  Wait a bit, discard chars, try again */
    msleep ( 1000 );
    if ( tcflush ( scanfd, TCIFLUSH ) < 0 )
	return -1;
    timeout = 10000;
    /* If we don't get it this time, give up */
    return get_ack ();
}
Exemplo n.º 7
0
/* Main sender function. Taken from the state diagram on slide 6, chapter 5 */
void sender(int window, int timeout) {
	 int base = 1;
	 int nextseqnum = 1;
	 bool allsent = false;
	 PQueue sendQ;
	 pqueue_init(&sendQ, window);

	 while ( !(allsent && pqueue_empty(&sendQ)) ) {
		  int acknum = -1;

		  /* Send new data */
		  if (!allsent && nextseqnum < base + window) {
			   Packet* packet = add_packet(&sendQ, nextseqnum);
			   if (packet == NULL) {
					allsent = true;
			   } else {
					send_packet(packet);
					if (base == nextseqnum)
						 start_timer(timeout);
					nextseqnum++;
			   }
		  }
		  
		  /* Attempt to receive an ACK. */
		  acknum = get_ack(0);
		  if (acknum > 0) {
			   base = acknum + 1;
			   if (base == nextseqnum)
					stop_timer();
			   else
					start_timer(timeout);
		  }

		  /* Clean up the queue */
		  while (!pqueue_empty(&sendQ) && pqueue_head(&sendQ)->seqn < base) {
			   pqueue_pop(&sendQ);
		  }
		  
		  /* Handle timeouts */
		  if (cnt_active && cnt_time >= cnt_timeout) {
			   start_timer(cnt_timeout);
			   pqueue_map(&sendQ, &send_packet);
		  }
		  pqueue_debug_print(&sendQ);
	 }
	 
	 pqueue_destroy(&sendQ);
}
Exemplo n.º 8
0
/**
 * receive the packet, save it into buffer
 * send corresponding ack back
 * @param dl, the handler
 * @param pkt, the received packet
 * @return 0 on success, -1 if fails
 */
int dl_recv(download_t *dl, packet_t *pkt) {
    uint32_t seq;
    size_t offset;

    if (dl->finished) {
        return 0;
    }

    /* do not update rtt until start */
    if (dl->started && !dl->block_update) {
        update_rtt(&dl->rtt, &dl->dev, dl->ts);
    } else { /* record data_len for the first time */
        dl->data_length = GET_DATA_LEN(pkt);
        dl->started = 1;
        dl->block_update = 0;
    }

    seq = GET_SEQ(pkt);
    offset = (seq - 1) * dl->data_length ;
    // discard data packet with seq number not sitting in current receive window
    //   or size exceeds the buffer length.
    if( ! seq_fit_in(&dl->rwin, seq) || offset + GET_DATA_LEN(pkt) > BT_CHUNK_SIZE){
        return -1;
    }

    if(! seq_exist_in(&dl->rwin, seq)){
        memcpy(dl->buffer + offset, GET_DATA(pkt), GET_DATA_LEN(pkt));
        recvwin_mark(&dl->rwin, seq);
    }

    send_ack(dl->p_index, get_ack(dl));

    dl->ts = get_timestamp_now();
    dl->timeout_cnt = 0;

    if ( (dl->next_pkt_expected -1)* dl->data_length >= BT_CHUNK_SIZE) {
        dl->finished = 1;
    }

    return 0;
}
Exemplo n.º 9
0
static inline void	treat_aknowledgment(edcl_packet_t*	packet,
					    unsigned int*	offset,
					    unsigned int*	size,
					    unsigned int*	sequence,
					    unsigned int*	nb_ack)

{
	/* We've been aknowledge, keep sending */
	if (get_ack(packet->header)) {
		*offset += min(*size, MAX_DATA_SIZE);
		*size -= min(*size, MAX_DATA_SIZE);
		++(*sequence);
		++(*nb_ack);
	}
	/* The sequence number was wrong, fix it */
	else {
		if (config.verbose)
			fprintf(stderr,
				"  Wrong sequence number (%d) should be: %d.\n",
				*sequence, get_sequence(packet->header));
		*sequence = get_sequence(packet->header);
	}
}
Exemplo n.º 10
0
/* Description: Recieve a packet and send it.
 * Author: Albin Severinson
 * Date: 03/03/15
 */
int send_packet(bstring packet)
{
  int rc = 0;
  int i = 0;
  int j = 0;
  char byte = 0;

  debug("[SENDING]: %s", bdata(packet));

  //Store packet size
  int data_size = blength(packet);

  for(j = 0;j < MAX_PACKET_RESEND;j++){
    debug("[SENDING PACKET] size: %d try: %d", data_size, j);

    //Transmit one byte at a time
    for(i = 0;i < data_size;i++){
      byte = bchar(packet, i);
      send_byte(byte);
      //debug("Sent [%d = %d]", i, byte);
    }

    //Wait for ACK frame
    if(data_size != 1){
      rc = get_ack();
      
      //Return if we got the ACK
      if(rc == 0){
        bdestroy(packet);
        return 0;
      }
    }
  }

  bdestroy(packet);
  return -1;
}
Exemplo n.º 11
0
static int find_common(struct fetch_negotiator *negotiator,
		       struct fetch_pack_args *args,
		       int fd[2], struct object_id *result_oid,
		       struct ref *refs)
{
	int fetching;
	int count = 0, flushes = 0, flush_at = INITIAL_FLUSH, retval;
	const struct object_id *oid;
	unsigned in_vain = 0;
	int got_continue = 0;
	int got_ready = 0;
	struct strbuf req_buf = STRBUF_INIT;
	size_t state_len = 0;

	if (args->stateless_rpc && multi_ack == 1)
		die(_("--stateless-rpc requires multi_ack_detailed"));

	if (!args->no_dependents) {
		mark_tips(negotiator, args->negotiation_tips);
		for_each_cached_alternate(negotiator, insert_one_alternate_object);
	}

	fetching = 0;
	for ( ; refs ; refs = refs->next) {
		struct object_id *remote = &refs->old_oid;
		const char *remote_hex;
		struct object *o;

		/*
		 * If that object is complete (i.e. it is an ancestor of a
		 * local ref), we tell them we have it but do not have to
		 * tell them about its ancestors, which they already know
		 * about.
		 *
		 * We use lookup_object here because we are only
		 * interested in the case we *know* the object is
		 * reachable and we have already scanned it.
		 *
		 * Do this only if args->no_dependents is false (if it is true,
		 * we cannot trust the object flags).
		 */
		if (!args->no_dependents &&
		    ((o = lookup_object(the_repository, remote->hash)) != NULL) &&
				(o->flags & COMPLETE)) {
			continue;
		}

		remote_hex = oid_to_hex(remote);
		if (!fetching) {
			struct strbuf c = STRBUF_INIT;
			if (multi_ack == 2)     strbuf_addstr(&c, " multi_ack_detailed");
			if (multi_ack == 1)     strbuf_addstr(&c, " multi_ack");
			if (no_done)            strbuf_addstr(&c, " no-done");
			if (use_sideband == 2)  strbuf_addstr(&c, " side-band-64k");
			if (use_sideband == 1)  strbuf_addstr(&c, " side-band");
			if (args->deepen_relative) strbuf_addstr(&c, " deepen-relative");
			if (args->use_thin_pack) strbuf_addstr(&c, " thin-pack");
			if (args->no_progress)   strbuf_addstr(&c, " no-progress");
			if (args->include_tag)   strbuf_addstr(&c, " include-tag");
			if (prefer_ofs_delta)   strbuf_addstr(&c, " ofs-delta");
			if (deepen_since_ok)    strbuf_addstr(&c, " deepen-since");
			if (deepen_not_ok)      strbuf_addstr(&c, " deepen-not");
			if (agent_supported)    strbuf_addf(&c, " agent=%s",
							    git_user_agent_sanitized());
			if (args->filter_options.choice)
				strbuf_addstr(&c, " filter");
			packet_buf_write(&req_buf, "want %s%s\n", remote_hex, c.buf);
			strbuf_release(&c);
		} else
			packet_buf_write(&req_buf, "want %s\n", remote_hex);
		fetching++;
	}

	if (!fetching) {
		strbuf_release(&req_buf);
		packet_flush(fd[1]);
		return 1;
	}

	if (is_repository_shallow(the_repository))
		write_shallow_commits(&req_buf, 1, NULL);
	if (args->depth > 0)
		packet_buf_write(&req_buf, "deepen %d", args->depth);
	if (args->deepen_since) {
		timestamp_t max_age = approxidate(args->deepen_since);
		packet_buf_write(&req_buf, "deepen-since %"PRItime, max_age);
	}
	if (args->deepen_not) {
		int i;
		for (i = 0; i < args->deepen_not->nr; i++) {
			struct string_list_item *s = args->deepen_not->items + i;
			packet_buf_write(&req_buf, "deepen-not %s", s->string);
		}
	}
	if (server_supports_filtering && args->filter_options.choice)
		packet_buf_write(&req_buf, "filter %s",
				 args->filter_options.filter_spec);
	packet_buf_flush(&req_buf);
	state_len = req_buf.len;

	if (args->deepen) {
		char *line;
		const char *arg;
		struct object_id oid;

		send_request(args, fd[1], &req_buf);
		while ((line = packet_read_line(fd[0], NULL))) {
			if (skip_prefix(line, "shallow ", &arg)) {
				if (get_oid_hex(arg, &oid))
					die(_("invalid shallow line: %s"), line);
				register_shallow(the_repository, &oid);
				continue;
			}
			if (skip_prefix(line, "unshallow ", &arg)) {
				if (get_oid_hex(arg, &oid))
					die(_("invalid unshallow line: %s"), line);
				if (!lookup_object(the_repository, oid.hash))
					die(_("object not found: %s"), line);
				/* make sure that it is parsed as shallow */
				if (!parse_object(the_repository, &oid))
					die(_("error in object: %s"), line);
				if (unregister_shallow(&oid))
					die(_("no shallow found: %s"), line);
				continue;
			}
			die(_("expected shallow/unshallow, got %s"), line);
		}
	} else if (!args->stateless_rpc)
		send_request(args, fd[1], &req_buf);

	if (!args->stateless_rpc) {
		/* If we aren't using the stateless-rpc interface
		 * we don't need to retain the headers.
		 */
		strbuf_setlen(&req_buf, 0);
		state_len = 0;
	}

	flushes = 0;
	retval = -1;
	if (args->no_dependents)
		goto done;
	while ((oid = negotiator->next(negotiator))) {
		packet_buf_write(&req_buf, "have %s\n", oid_to_hex(oid));
		print_verbose(args, "have %s", oid_to_hex(oid));
		in_vain++;
		if (flush_at <= ++count) {
			int ack;

			packet_buf_flush(&req_buf);
			send_request(args, fd[1], &req_buf);
			strbuf_setlen(&req_buf, state_len);
			flushes++;
			flush_at = next_flush(args->stateless_rpc, count);

			/*
			 * We keep one window "ahead" of the other side, and
			 * will wait for an ACK only on the next one
			 */
			if (!args->stateless_rpc && count == INITIAL_FLUSH)
				continue;

			consume_shallow_list(args, fd[0]);
			do {
				ack = get_ack(fd[0], result_oid);
				if (ack)
					print_verbose(args, _("got %s %d %s"), "ack",
						      ack, oid_to_hex(result_oid));
				switch (ack) {
				case ACK:
					flushes = 0;
					multi_ack = 0;
					retval = 0;
					goto done;
				case ACK_common:
				case ACK_ready:
				case ACK_continue: {
					struct commit *commit =
						lookup_commit(the_repository,
							      result_oid);
					int was_common;

					if (!commit)
						die(_("invalid commit %s"), oid_to_hex(result_oid));
					was_common = negotiator->ack(negotiator, commit);
					if (args->stateless_rpc
					 && ack == ACK_common
					 && !was_common) {
						/* We need to replay the have for this object
						 * on the next RPC request so the peer knows
						 * it is in common with us.
						 */
						const char *hex = oid_to_hex(result_oid);
						packet_buf_write(&req_buf, "have %s\n", hex);
						state_len = req_buf.len;
						/*
						 * Reset in_vain because an ack
						 * for this commit has not been
						 * seen.
						 */
						in_vain = 0;
					} else if (!args->stateless_rpc
						   || ack != ACK_common)
						in_vain = 0;
					retval = 0;
					got_continue = 1;
					if (ack == ACK_ready)
						got_ready = 1;
					break;
					}
				}
			} while (ack);
			flushes--;
			if (got_continue && MAX_IN_VAIN < in_vain) {
				print_verbose(args, _("giving up"));
				break; /* give up */
			}
			if (got_ready)
				break;
		}
	}
done:
	if (!got_ready || !no_done) {
		packet_buf_write(&req_buf, "done\n");
		send_request(args, fd[1], &req_buf);
	}
	print_verbose(args, _("done"));
	if (retval != 0) {
		multi_ack = 0;
		flushes++;
	}
	strbuf_release(&req_buf);

	if (!got_ready || !no_done)
		consume_shallow_list(args, fd[0]);
	while (flushes || multi_ack) {
		int ack = get_ack(fd[0], result_oid);
		if (ack) {
			print_verbose(args, _("got %s (%d) %s"), "ack",
				      ack, oid_to_hex(result_oid));
			if (ack == ACK)
				return 0;
			multi_ack = 1;
			continue;
		}
		flushes--;
	}
	/* it is no error to fetch into a completely empty repo */
	return count ? retval : 0;
}
Exemplo n.º 12
0
static int find_common(int fd[2], unsigned char *result_sha1,
		       struct ref *refs)
{
	int fetching;
	int count = 0, flushes = 0, retval;
	const unsigned char *sha1;
	unsigned in_vain = 0;
	int got_continue = 0;

	if (marked)
		for_each_ref(clear_marks, NULL);
	marked = 1;

	for_each_ref(rev_list_insert_ref, NULL);

	fetching = 0;
	for ( ; refs ; refs = refs->next) {
		unsigned char *remote = refs->old_sha1;
		struct object *o;

		/*
		 * If that object is complete (i.e. it is an ancestor of a
		 * local ref), we tell them we have it but do not have to
		 * tell them about its ancestors, which they already know
		 * about.
		 *
		 * We use lookup_object here because we are only
		 * interested in the case we *know* the object is
		 * reachable and we have already scanned it.
		 */
		if (((o = lookup_object(remote)) != NULL) &&
				(o->flags & COMPLETE)) {
			continue;
		}

		if (!fetching)
			packet_write(fd[1], "want %s%s%s%s%s%s%s%s\n",
				     sha1_to_hex(remote),
				     (multi_ack ? " multi_ack" : ""),
				     (use_sideband == 2 ? " side-band-64k" : ""),
				     (use_sideband == 1 ? " side-band" : ""),
				     (args.use_thin_pack ? " thin-pack" : ""),
				     (args.no_progress ? " no-progress" : ""),
				     (args.include_tag ? " include-tag" : ""),
				     " ofs-delta");
		else
			packet_write(fd[1], "want %s\n", sha1_to_hex(remote));
		fetching++;
	}
	if (is_repository_shallow())
		write_shallow_commits(fd[1], 1);
	if (args.depth > 0)
		packet_write(fd[1], "deepen %d", args.depth);
	packet_flush(fd[1]);
	if (!fetching)
		return 1;

	if (args.depth > 0) {
		char line[1024];
		unsigned char sha1[20];

		while (packet_read_line(fd[0], line, sizeof(line))) {
			if (!prefixcmp(line, "shallow ")) {
				if (get_sha1_hex(line + 8, sha1))
					die("invalid shallow line: %s", line);
				register_shallow(sha1);
				continue;
			}
			if (!prefixcmp(line, "unshallow ")) {
				if (get_sha1_hex(line + 10, sha1))
					die("invalid unshallow line: %s", line);
				if (!lookup_object(sha1))
					die("object not found: %s", line);
				/* make sure that it is parsed as shallow */
				if (!parse_object(sha1))
					die("error in object: %s", line);
				if (unregister_shallow(sha1))
					die("no shallow found: %s", line);
				continue;
			}
			die("expected shallow/unshallow, got %s", line);
		}
	}

	flushes = 0;
	retval = -1;
	while ((sha1 = get_rev())) {
		packet_write(fd[1], "have %s\n", sha1_to_hex(sha1));
		if (args.verbose)
			fprintf(stderr, "have %s\n", sha1_to_hex(sha1));
		in_vain++;
		if (!(31 & ++count)) {
			int ack;

			packet_flush(fd[1]);
			flushes++;

			/*
			 * We keep one window "ahead" of the other side, and
			 * will wait for an ACK only on the next one
			 */
			if (count == 32)
				continue;

			do {
				ack = get_ack(fd[0], result_sha1);
				if (args.verbose && ack)
					fprintf(stderr, "got ack %d %s\n", ack,
							sha1_to_hex(result_sha1));
				if (ack == 1) {
					flushes = 0;
					multi_ack = 0;
					retval = 0;
					goto done;
				} else if (ack == 2) {
					struct commit *commit =
						lookup_commit(result_sha1);
					mark_common(commit, 0, 1);
					retval = 0;
					in_vain = 0;
					got_continue = 1;
				}
			} while (ack);
			flushes--;
			if (got_continue && MAX_IN_VAIN < in_vain) {
				if (args.verbose)
					fprintf(stderr, "giving up\n");
				break; /* give up */
			}
		}
	}
done:
	packet_write(fd[1], "done\n");
	if (args.verbose)
		fprintf(stderr, "done\n");
	if (retval != 0) {
		multi_ack = 0;
		flushes++;
	}
	while (flushes || multi_ack) {
		int ack = get_ack(fd[0], result_sha1);
		if (ack) {
			if (args.verbose)
				fprintf(stderr, "got ack (%d) %s\n", ack,
					sha1_to_hex(result_sha1));
			if (ack == 1)
				return 0;
			multi_ack = 1;
			continue;
		}
		flushes--;
	}
	/* it is no error to fetch into a completely empty repo */
	return count ? retval : 0;
}
Exemplo n.º 13
0
/**
 * Send an edcl packet and fragment it if max_packet_size < data_size
 */
static int		send_fragmented(void)
{
	unsigned int		nb_ack_packet = 0;
	unsigned int		address_offset = 0;
	unsigned int		nb_sent_packet = 0;
	unsigned int		local_data_size = config.data_size;
	edcl_packet_t*		packet = NULL;

	/* Allocating the packet of the packet */
	packet = calloc(1, min(local_data_size, MAX_DATA_SIZE) + sizeof (edcl_header_t));
	if (packet == NULL)
		goto error_malloc;

	do {
		/* Filling up the edcl header */
		clear_header(packet->header);
		set_operation(packet->header, WRITE_OP);
		set_sequence(packet->header, config.sequence_number);
		set_address(packet->header, config.memory_address + address_offset);
		set_length(packet->header, min(local_data_size, MAX_DATA_SIZE));

		if (config.verbose)
			fprintf(stderr,
				" [%d] Trying to write at 0x%08x.",
				config.sequence_number,
				config.memory_address + address_offset);

		/* Copying the data in the packet */
		memcpy(packet->data,
		       config.data_c + address_offset,
		       min(local_data_size, MAX_DATA_SIZE));

		/* Sending the packet to the ethernet IP */
		if (sendto(config.socket,
			   packet,
			   min(local_data_size, MAX_DATA_SIZE) + sizeof (edcl_header_t),
			   0, config.serv_info->ai_addr, config.serv_info->ai_addrlen)
		    == -1)
			goto error_send;

		/* Waiting for the aknowledgment */
		if (recvfrom(config.socket,  packet,
			     sizeof (edcl_header_t) + min(local_data_size, MAX_DATA_SIZE),
			     0, NULL, 0) == -1)
			goto error_recvfrom;

		/* We've been aknowledge, keep sending */
		if (get_ack(packet->header)) {
			if (config.verbose)
				fprintf(stderr,
					"\t[OK]\n");
			address_offset += min(local_data_size, MAX_DATA_SIZE);
			local_data_size -= min(local_data_size, MAX_DATA_SIZE);
			++config.sequence_number;
			++nb_ack_packet;
		}
		/* The sequence number was wrong, fix it */
		else {
			if (config.verbose)
				fprintf(stderr,
					"\t[Failed]\n  Wrong sequence number (%d) should be: %d. Fixed.\n",
					config.sequence_number, get_sequence(packet->header));
			config.sequence_number = get_sequence(packet->header);
		}

		++nb_sent_packet;
	} while (local_data_size > 0);

	if (config.verbose) {
		fprintf(stderr,
			"The datas have been fragmented in %d packets.\n", nb_ack_packet);
		fprintf(stderr,
			"\t %d packets have been sent (%d have been lost).\n",
			nb_sent_packet,
			nb_sent_packet - nb_ack_packet);
	}

	/* Releasing ressources */
	free(packet);

	return (0);

 error_recvfrom:
 error_send:
	if (config.verbose)
		fprintf(stderr,
			"Error while sending the packet.\n");
	free(packet);
	return (errno);
 error_malloc:
	if (config.verbose)
		fprintf(stderr,
			"Unable to allocate the packet.\n");
	return (errno);
}
Exemplo n.º 14
0
void rwqAction(int sockID, struct sockaddr_in sockInfo, struct PARAMS *params)
{
	unsigned short int bnum = 1;
	unsigned short int sz  = 0;

	tftp_ack_hdr ack;
	tftp_rwq_hdr rwq;
	tftp_data_hdr data;
	char buffer[MAX_BUFFER];
	
	bzero(&data, sizeof(tftp_data_hdr));
	bzero(&rwq, sizeof(tftp_rwq_hdr));

	rwq_deserialize(&rwq, buffer);

	if(mode_transfer(rwq.mode, "octet", params) == -1)
	{
		sendError(sockID, sockInfo, RFC1350_OP_ERROR, RFC1350_ERR_NOTDEF, "Set transfer mode to octet");
		return;
	}

	FILE *pFile = NULL;
	if((pFile = open_file(rwq.filename, "rb", params)) == NULL)
	{
		return;
	}

	if(timeout_option(&rwq, params) == 1)
	{
		sendACKOpt(sockID, sockInfo, "timeout", params->rexmt);
	}

	int t_out = 0;
	int intents = 5;
	
	do
	{
		bzero(buffer, MAX_BUFFER);
		bzero(&data, sizeof(tftp_data_hdr));

		data.opcode = RFC1350_OP_DATA;
		data.num_block = bnum++;

		sz = fread(data.data, 1, RFC1350_BLOCKSIZE, pFile);
		sz = data_serialize(&data, buffer, sz);		
	
		bzero(&ack, sizeof(tftp_ack_hdr));
		intents = 5;
		
		do
		{
			sendInfo(sockID, sockInfo, buffer, sz);			
			if((t_out = select_func(sockID, params->rexmt)) == 1)
			{
				get_ack(&ack, sockID, sockInfo, params);
				ack_serialize(&ack, buffer);
			}
		}while(t_out == 0 && --intents);
	}while((sz - SHORT_SIZE * 2) == RFC1350_BLOCKSIZE && t_out != -1);

	if(intents == 0)
	{
		printf("Transfer timed out\n");
	}

	fclose(pFile);
}
Exemplo n.º 15
0
/**
 *
 * @param fd
 *  The netlink socket fd
 * @param type
 *  The type of netlink message
 * @param data
 *  The data to send
 * @param size
 *  The length of the data in bytes
 * @return
 *  This function returns a positive sequence number on success, else -errno.
 */
static int audit_send(int fd, int type, const void* data, size_t size) {
    int rc;
    static int16_t sequence = 0;
    struct audit_message req;
    struct sockaddr_nl addr;

    memset(&req, 0, sizeof(req));
    memset(&addr, 0, sizeof(addr));

    /* We always send netlink messaged */
    addr.nl_family = AF_NETLINK;

    /* Set up the netlink headers */
    req.nlh.nlmsg_type = type;
    req.nlh.nlmsg_len = NLMSG_SPACE(size);
    req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;

    /*
     * Check for a valid fd, even though sendto would catch this, its easier
     * to always blindly increment the sequence number
     */
    if (fd < 0) {
        return -EBADF;
    }

    /* Ensure the message is not too big */
    if (NLMSG_SPACE(size) > MAX_AUDIT_MESSAGE_LENGTH) {
        return -EINVAL;
    }

    /* Only memcpy in the data if it was specified */
    if (size && data) {
        memcpy(NLMSG_DATA(&req.nlh), data, size);
    }

    /*
     * Only increment the sequence number on a guarantee
     * you will send it to the kernel.
     *
     * Also, the sequence is defined as a u32 in the kernel
     * struct. Using an int here might not work on 32/64 bit splits. A
     * signed 64 bit value can overflow a u32..but a u32
     * might not fit in the response, so we need to use s32.
     * Which is still kind of hackish since int could be 16 bits
     * in size. The only safe type to use here is a signed 16
     * bit value.
     */
    req.nlh.nlmsg_seq = ++sequence;

    /* While failing and its due to interrupts */

    rc = TEMP_FAILURE_RETRY(sendto(fd, &req, req.nlh.nlmsg_len, 0,
                                   (struct sockaddr*)&addr, sizeof(addr)));

    /* Not all the bytes were sent */
    if (rc < 0) {
        rc = -errno;
        goto out;
    } else if ((uint32_t)rc != req.nlh.nlmsg_len) {
        rc = -EPROTO;
        goto out;
    }

    /* We sent all the bytes, get the ack */
    rc = get_ack(fd);

    /* If the ack failed, return the error, else return the sequence number */
    rc = (rc == 0) ? (int)sequence : rc;

out:
    /* Don't let sequence roll to negative */
    if (sequence < 0) {
        sequence = 0;
    }

    return rc;
}
Exemplo n.º 16
0
static int find_common(struct fetch_pack_args *args,
		       int fd[2], unsigned char *result_sha1,
		       struct ref *refs)
{
	int fetching;
	int count = 0, flushes = 0, flush_at = INITIAL_FLUSH, retval;
	const unsigned char *sha1;
	unsigned in_vain = 0;
	int got_continue = 0;
	int got_ready = 0;
	struct strbuf req_buf = STRBUF_INIT;
	size_t state_len = 0;

	if (args->stateless_rpc && multi_ack == 1)
		die("--stateless-rpc requires multi_ack_detailed");
	if (marked)
		for_each_ref(clear_marks, NULL);
	marked = 1;

	for_each_ref(rev_list_insert_ref, NULL);
	for_each_alternate_ref(insert_one_alternate_ref, NULL);

	fetching = 0;
	for ( ; refs ; refs = refs->next) {
		unsigned char *remote = refs->old_sha1;
		const char *remote_hex;
		struct object *o;

		/*
		 * If that object is complete (i.e. it is an ancestor of a
		 * local ref), we tell them we have it but do not have to
		 * tell them about its ancestors, which they already know
		 * about.
		 *
		 * We use lookup_object here because we are only
		 * interested in the case we *know* the object is
		 * reachable and we have already scanned it.
		 */
		if (((o = lookup_object(remote)) != NULL) &&
				(o->flags & COMPLETE)) {
			continue;
		}

		remote_hex = sha1_to_hex(remote);
		if (!fetching) {
			struct strbuf c = STRBUF_INIT;
			if (multi_ack == 2)     strbuf_addstr(&c, " multi_ack_detailed");
			if (multi_ack == 1)     strbuf_addstr(&c, " multi_ack");
			if (no_done)            strbuf_addstr(&c, " no-done");
			if (use_sideband == 2)  strbuf_addstr(&c, " side-band-64k");
			if (use_sideband == 1)  strbuf_addstr(&c, " side-band");
			if (args->use_thin_pack) strbuf_addstr(&c, " thin-pack");
			if (args->no_progress)   strbuf_addstr(&c, " no-progress");
			if (args->include_tag)   strbuf_addstr(&c, " include-tag");
			if (prefer_ofs_delta)   strbuf_addstr(&c, " ofs-delta");
			if (agent_supported)    strbuf_addf(&c, " agent=%s",
							    git_user_agent_sanitized());
			packet_buf_write(&req_buf, "want %s%s\n", remote_hex, c.buf);
			strbuf_release(&c);
		} else
			packet_buf_write(&req_buf, "want %s\n", remote_hex);
		fetching++;
	}

	if (!fetching) {
		strbuf_release(&req_buf);
		packet_flush(fd[1]);
		return 1;
	}

	if (is_repository_shallow())
		write_shallow_commits(&req_buf, 1, NULL);
	if (args->depth > 0)
		packet_buf_write(&req_buf, "deepen %d", args->depth);
	packet_buf_flush(&req_buf);
	state_len = req_buf.len;

	if (args->depth > 0) {
		char *line;
		const char *arg;
		unsigned char sha1[20];

		send_request(args, fd[1], &req_buf);
		while ((line = packet_read_line(fd[0], NULL))) {
			if (skip_prefix(line, "shallow ", &arg)) {
				if (get_sha1_hex(arg, sha1))
					die("invalid shallow line: %s", line);
				register_shallow(sha1);
				continue;
			}
			if (skip_prefix(line, "unshallow ", &arg)) {
				if (get_sha1_hex(arg, sha1))
					die("invalid unshallow line: %s", line);
				if (!lookup_object(sha1))
					die("object not found: %s", line);
				/* make sure that it is parsed as shallow */
				if (!parse_object(sha1))
					die("error in object: %s", line);
				if (unregister_shallow(sha1))
					die("no shallow found: %s", line);
				continue;
			}
			die("expected shallow/unshallow, got %s", line);
		}
	} else if (!args->stateless_rpc)
		send_request(args, fd[1], &req_buf);

	if (!args->stateless_rpc) {
		/* If we aren't using the stateless-rpc interface
		 * we don't need to retain the headers.
		 */
		strbuf_setlen(&req_buf, 0);
		state_len = 0;
	}

	flushes = 0;
	retval = -1;
	while ((sha1 = get_rev())) {
		packet_buf_write(&req_buf, "have %s\n", sha1_to_hex(sha1));
		if (args->verbose)
			fprintf(stderr, "have %s\n", sha1_to_hex(sha1));
		in_vain++;
		if (flush_at <= ++count) {
			int ack;

			packet_buf_flush(&req_buf);
			send_request(args, fd[1], &req_buf);
			strbuf_setlen(&req_buf, state_len);
			flushes++;
			flush_at = next_flush(args, count);

			/*
			 * We keep one window "ahead" of the other side, and
			 * will wait for an ACK only on the next one
			 */
			if (!args->stateless_rpc && count == INITIAL_FLUSH)
				continue;

			consume_shallow_list(args, fd[0]);
			do {
				ack = get_ack(fd[0], result_sha1);
				if (args->verbose && ack)
					fprintf(stderr, "got ack %d %s\n", ack,
							sha1_to_hex(result_sha1));
				switch (ack) {
				case ACK:
					flushes = 0;
					multi_ack = 0;
					retval = 0;
					goto done;
				case ACK_common:
				case ACK_ready:
				case ACK_continue: {
					struct commit *commit =
						lookup_commit(result_sha1);
					if (!commit)
						die("invalid commit %s", sha1_to_hex(result_sha1));
					if (args->stateless_rpc
					 && ack == ACK_common
					 && !(commit->object.flags & COMMON)) {
						/* We need to replay the have for this object
						 * on the next RPC request so the peer knows
						 * it is in common with us.
						 */
						const char *hex = sha1_to_hex(result_sha1);
						packet_buf_write(&req_buf, "have %s\n", hex);
						state_len = req_buf.len;
					}
					mark_common(commit, 0, 1);
					retval = 0;
					in_vain = 0;
					got_continue = 1;
					if (ack == ACK_ready) {
						clear_prio_queue(&rev_list);
						got_ready = 1;
					}
					break;
					}
				}
			} while (ack);
			flushes--;
			if (got_continue && MAX_IN_VAIN < in_vain) {
				if (args->verbose)
					fprintf(stderr, "giving up\n");
				break; /* give up */
			}
		}
	}
done:
	if (!got_ready || !no_done) {
		packet_buf_write(&req_buf, "done\n");
		send_request(args, fd[1], &req_buf);
	}
	if (args->verbose)
		fprintf(stderr, "done\n");
	if (retval != 0) {
		multi_ack = 0;
		flushes++;
	}
	strbuf_release(&req_buf);

	if (!got_ready || !no_done)
		consume_shallow_list(args, fd[0]);
	while (flushes || multi_ack) {
		int ack = get_ack(fd[0], result_sha1);
		if (ack) {
			if (args->verbose)
				fprintf(stderr, "got ack (%d) %s\n", ack,
					sha1_to_hex(result_sha1));
			if (ack == ACK)
				return 0;
			multi_ack = 1;
			continue;
		}
		flushes--;
	}
	/* it is no error to fetch into a completely empty repo */
	return count ? retval : 0;
}
Exemplo n.º 17
0
void send_commands()
{
    kvstore_cmd_t cmd;
    kvstore_ack_t ack;
    char buf[100];
    const char *delims = " ";
    char * parsed;
    int len;

    /* FIXME for now. Improve this by using a more
     * appropriate parser */
    char *op, *kv_key, *kv_val;
    //int ret;

    memset(&cmd, 0, sizeof(kvstore_cmd_t));
    memset(&ack, 0, sizeof(kvstore_ack_t));

    do {
        memset(buf, 0, sizeof(buf));

        printf("\n(kv) ");
        fflush(stdout);
        fgets(buf, sizeof(buf), stdin);

        parsed = strdup(buf);
        str_trim(&parsed);
        len = strlen(parsed);

        if (len == 0) {
            continue;
        }

        op = strtok(parsed, delims);

        // get the op
        kvstore_type_t kv_type = get_type(op);
        if (kv_type == KVSTORE_NONE) {
            printf("ERROR: Invalid Operation");
            continue;
        }

        switch (kv_type) {
            case KVSTORE_EXIT: return;
            default: break;
        }

        // get the key and message
        kv_key = strtok(NULL, delims);
        if (kv_key == NULL) {
            printf("ERROR: Invalid Operation");
            continue;
        }

        // if we're just using get
        if (kv_type == KVSTORE_GET) {
            kv_val = "";
        } else {
            kv_val = strtok(NULL, "\0");
        }

        // set the code and message then encrypt
        memset(&cmd, 0, sizeof(cmd));
        cmd.type = kv_type;
        strncpy((char *)&cmd.payload.key, kv_key, KVSTORE_KEY_LEN);
        strncpy((char *)&cmd.payload.val, kv_val, KVSTORE_VAL_LEN);

        cmd.payload.key[strlen(kv_key)] = '\0';
        // copy the IV
        memcpy(cmd.iv, iv, KVSTORE_AESIV_LEN);

        aes_setkey_enc(&aes, enckey, KVSTORE_AESKEY_BITS);
        aes_crypt_cbc(&aes, AES_ENCRYPT, sizeof(cmd.payload), iv,
                (const unsigned char *)&cmd.payload,
                (unsigned char *)&cmd.payload);

        if (send_data(&pfd, &cmd, sizeof(cmd))) {
            goto exit;
        }

        if (kv_type == KVSTORE_SET) {
            // just get the acknowledgement
            // TODO check content
            if (get_ack(&pfd, &ack)) {
                goto exit;
            }
            printf("OK");
        } else if (kv_type == KVSTORE_GET) {
            // get the data
            if(get_resp(&pfd, &cmd)) {
                goto exit;
            }
            aes_setkey_dec(&aes, enckey, KVSTORE_AESKEY_BITS);
            // now decrypt
            aes_crypt_cbc(&aes, AES_DECRYPT, sizeof(cmd.payload), cmd.iv,
                (const unsigned char *)&cmd.payload,
                (unsigned char *)&cmd.payload);
            printf("%s", cmd.payload.val);
        }

        // printf("op: %s, title: %s, data: %s\n", op, kv_key, kv_msg);
    } while(1);

exit:
    printf("error\n");
}