Example #1
0
// fill a packet from our outgoing queues and send it
static int
overlay_fill_send_packet(struct outgoing_packet *packet, time_ms_t now) {
  int i;
  IN();
  // while we're looking at queues, work out when to schedule another packet
  unschedule(&next_packet);
  next_packet.alarm=0;
  next_packet.deadline=0;
  
  for (i=0;i<OQ_MAX;i++){
    overlay_txqueue *queue=&overlay_tx[i];
    
    overlay_stuff_packet(packet, queue, now);
  }
  
  if(packet->buffer){
    if (config.debug.packetconstruction)
      ob_dump(packet->buffer,"assembled packet");
      
    if (overlay_broadcast_ensemble(packet->interface, &packet->dest, ob_ptr(packet->buffer), ob_position(packet->buffer))){
      // sendto failed. We probably don't have a valid route
      if (packet->unicast_subscriber){
	set_reachable(packet->unicast_subscriber, REACHABLE_NONE);
      }
    }
    ob_free(packet->buffer);
    RETURN(1);
  }
  RETURN(0);
  OUT();
}
Example #2
0
// mark the subscriber as reachable via reply unicast packet
int reachable_unicast(struct subscriber *subscriber, overlay_interface *interface, struct in_addr addr, int port){
  if (subscriber->reachable&REACHABLE)
    return -1;
  
  if (subscriber->node)
    return -1;
  
  subscriber->interface = interface;
  subscriber->address.sin_family = AF_INET;
  subscriber->address.sin_addr = addr;
  subscriber->address.sin_port = htons(port);
  set_reachable(subscriber, REACHABLE_UNICAST);
  
  return 0;
}
Example #3
0
/* Collection of unicast echo responses to detect working links */
int
overlay_mdp_service_probe(overlay_mdp_frame *mdp)
{
  IN();
  if (mdp->out.src.port!=MDP_PORT_ECHO || mdp->out.payload_length != sizeof(struct probe_contents)){
    WARN("Probe packets should be returned from remote echo port");
    RETURN(-1);
  }
  
  struct subscriber *peer = find_subscriber(mdp->out.src.sid, SID_SIZE, 0);
  if (peer->reachable == REACHABLE_SELF)
    RETURN(0);
  
  struct probe_contents probe;
  bcopy(&mdp->out.payload, &probe, sizeof(struct probe_contents));
  if (probe.addr.sin_family!=AF_INET)
    RETURN(WHY("Unsupported address family"));
  
  struct overlay_interface *interface = &overlay_interfaces[probe.interface];
  // if a peer is already reachable, and this probe would change the interface, ignore it
  // TODO track unicast links better in route_link.c
  if (peer->reachable & REACHABLE_INDIRECT)
    RETURN(0);
  if (peer->reachable & REACHABLE_DIRECT && peer->interface && peer->interface != interface)
    RETURN(0);

  peer->last_probe_response = gettime_ms();
  peer->interface = &overlay_interfaces[probe.interface];
  peer->address.sin_family = AF_INET;
  peer->address.sin_addr = probe.addr.sin_addr;
  peer->address.sin_port = probe.addr.sin_port;
  int r=REACHABLE_UNICAST;
  // Don't turn assumed|broadcast into unicast|broadcast
  if (!(peer->reachable & REACHABLE_ASSUMED))
    r |= (peer->reachable & REACHABLE_DIRECT);
  set_reachable(peer, r);
  RETURN(0);
  OUT();
}
Example #4
0
/* Read the slot, and try to decrypt it.
   Decryption is symmetric with encryption, so the same function is used
   for munging the slot before making use of it, whichever way we are going.
   Once munged, we then need to verify that the slot is valid, and if so
   unpack the details of the identity.
*/
int keyring_decrypt_pkr(keyring_file *k,keyring_context *c,
			const char *pin,int slot_number)
{
  int exit_code=1;
  unsigned char slot[KEYRING_PAGE_SIZE];
  unsigned char hash[crypto_hash_sha512_BYTES];
  unsigned char work[65536];
  keyring_identity *id=NULL; 

  /* 1. Read slot. */
  if (fseeko(k->file,slot_number*KEYRING_PAGE_SIZE,SEEK_SET))
    return WHY_perror("fseeko");
  if (fread(&slot[0],KEYRING_PAGE_SIZE,1,k->file)!=1)
    return WHY_perror("fread");
  /* 2. Decrypt data from slot. */
  if (keyring_munge_block(slot,KEYRING_PAGE_SIZE,
			  k->contexts[0]->KeyRingSalt,
			  k->contexts[0]->KeyRingSaltLen,
			  c->KeyRingPin,pin)) {
    WHY("keyring_munge_block() failed");
    goto kdp_safeexit;
  }  

  /* 3. Unpack contents of slot into a new identity in the provided context. */  
  id=keyring_unpack_identity(slot,pin);
  if (!id) {
    // Don't complain, because this happens routinely when trying pins against slots.
    // WHY("keyring_unpack_identity() failed");
    goto kdp_safeexit;
  }
  id->slot=slot_number;

  /* 4. Verify that slot is self-consistent (check MAC) */
  if (keyring_identity_mac(k->contexts[0],id,&slot[0],hash)) {
    WHY("could not calculate MAC for identity");
    goto kdp_safeexit;
  }
  /* compare hash to record */
  if (memcmp(hash,&slot[32],crypto_hash_sha512_BYTES))
    {      
      WHY("Slot is not valid (MAC mismatch)");
      dump("computed",hash,crypto_hash_sha512_BYTES);
      dump("stored",&slot[32],crypto_hash_sha512_BYTES);
      goto kdp_safeexit;
    }
  
  // add any unlocked subscribers to our memory table, flagged as local sid's
  int i=0;
  for (i=0;i<id->keypair_count;i++){
    if (id->keypairs[i]->type == KEYTYPE_CRYPTOBOX){
      struct subscriber *subscriber = find_subscriber(id->keypairs[i]->public_key, SID_SIZE, 1);
      if (subscriber){
	set_reachable(subscriber, REACHABLE_SELF);
	if (!my_subscriber)
	  my_subscriber=subscriber;
      }
    }
  }
  
  /* Well, it's all fine, so add the id into the context and return */
  c->identities[c->identity_count++]=id;
  
  return 0;

 kdp_safeexit:
  /* Clean up any potentially sensitive data before exiting */
  bzero(slot,KEYRING_PAGE_SIZE);
  bzero(hash,crypto_hash_sha512_BYTES);
  bzero(&work[0],65536);
  if (id) keyring_free_identity(id); id=NULL;
  return exit_code;
}