示例#1
0
lob_t remote_encrypt(remote_t remote, local_t local, lob_t inner)
{
  uint8_t secret[crypto_box_BEFORENMBYTES], nonce[24], shared[24+crypto_box_BEFORENMBYTES], hash[32], csid = 0x3a;
  lob_t outer;
  size_t inner_len;

  outer = lob_new();
  lob_head(outer,&csid,1);
  inner_len = lob_len(inner);
  if(!lob_body(outer,NULL,32+24+inner_len+crypto_secretbox_MACBYTES+16)) return lob_free(outer);

  // copy in the ephemeral public key/nonce
  memcpy(outer->body, remote->ekey, 32);
  randombytes(nonce,24);
  memcpy(outer->body+32, nonce, 24);

  // get the shared secret to create the nonce+key for the open aes
  crypto_box_beforenm(secret, remote->key, remote->esecret);

  // encrypt the inner
  if(crypto_secretbox_easy(outer->body+32+24,
    lob_raw(inner),
    inner_len,
    nonce,
    secret) != 0) return lob_free(outer);

  // generate secret for hmac
  crypto_box_beforenm(secret, remote->key, local->secret);
  memcpy(shared,nonce,24);
  memcpy(shared+24,secret,crypto_box_BEFORENMBYTES);
  e3x_hash(shared,24+crypto_box_BEFORENMBYTES,hash);
  crypto_onetimeauth(outer->body+32+24+inner_len+crypto_secretbox_MACBYTES, outer->body, outer->body_len-16, hash);

  return outer;
}
示例#2
0
lob_t local_decrypt(local_t local, lob_t outer)
{
  uint8_t key[uECC_BYTES*2], shared[uECC_BYTES], iv[16], hash[32];
  lob_t inner, tmp;

//  * `KEY` - 21 bytes, the sender's ephemeral exchange public key in compressed format
//  * `IV` - 4 bytes, a random but unique value determined by the sender
//  * `INNER` - (minimum 21+2 bytes) the AES-128-CTR encrypted inner packet ciphertext
//  * `HMAC` - 4 bytes, the calculated HMAC of all of the previous KEY+INNER bytes

  if(outer->body_len <= (21+4+0+4)) return NULL;
  tmp = lob_new();
  if(!lob_body(tmp,NULL,outer->body_len-(4+21+4))) return lob_free(tmp);

  // get the shared secret to create the iv+key for the open aes
  uECC_decompress(outer->body,key);
  if(!uECC_shared_secret(key, local->secret, shared)) return lob_free(tmp);
  e3x_hash(shared,uECC_BYTES,hash);
  fold1(hash,hash);
  memset(iv,0,16);
  memcpy(iv,outer->body+21,4);

  // decrypt the inner
  aes_128_ctr(hash,tmp->body_len,iv,outer->body+4+21,tmp->body);

  // load inner packet
  inner = lob_parse(tmp->body,tmp->body_len);
  lob_free(tmp);
  return inner;
}
示例#3
0
local_t local_new(lob_t keys, lob_t secrets)
{
  local_t local;
  lob_t key, secret;

  if(!keys) keys = lob_linked(secrets); // for convenience
  key = lob_get_base32(keys,"3a");
  if(!key) return LOG("missing key");
  if(key->body_len != crypto_box_PUBLICKEYBYTES) return LOG("invalid key %d != %d",key->body_len,crypto_box_PUBLICKEYBYTES);

  secret = lob_get_base32(secrets,"3a");
  if(!secret) return LOG("missing secret");
  if(secret->body_len != crypto_box_SECRETKEYBYTES) return LOG("invalid secret %d != %d",secret->body_len,crypto_box_SECRETKEYBYTES);

  if(!(local = malloc(sizeof(struct local_struct)))) return NULL;
  memset(local,0,sizeof (struct local_struct));

  // copy in key/secret data
  memcpy(local->key,key->body,key->body_len);
  memcpy(local->secret,secret->body,secret->body_len);
  lob_free(key);
  lob_free(secret);

  return local;
}
示例#4
0
lob_t local_decrypt(local_t local, lob_t outer)
{
  uint8_t secret[crypto_box_BEFORENMBYTES];
  lob_t inner, tmp;

//  * `KEY` - 32 bytes, the sending exchange's ephemeral public key
//  * `NONCE` - 24 bytes, randomly generated
//  * `CIPHERTEXT` - the inner packet bytes encrypted using secretbox() using the `NONCE` as the nonce and the shared secret (derived from the recipients endpoint key and the included ephemeral key) as the key
//  * `AUTH` - 16 bytes, the calculated onetimeauth(`KEY` + `INNER`, SHA256(`NONCE` + secret)) using the shared secret derived from both endpoint keys, the hashing is to minimize the chance that the same key input is ever used twice

  if(outer->body_len <= (32+24+crypto_secretbox_MACBYTES+16)) return NULL;
  tmp = lob_new();
  if(!lob_body(tmp,NULL,outer->body_len-(32+24+crypto_secretbox_MACBYTES+16))) return lob_free(tmp);

  // get the shared secret
  crypto_box_beforenm(secret, outer->body, local->secret);

  // decrypt the inner
  if(crypto_secretbox_open_easy(tmp->body,
    outer->body+32+24,
    tmp->body_len+crypto_secretbox_MACBYTES,
    outer->body+32,
    secret) != 0) return lob_free(tmp);

  // load inner packet
  inner = lob_parse(tmp->body,tmp->body_len);
  lob_free(tmp);

  return inner;
}
示例#5
0
lob_t remote_encrypt(remote_t remote, local_t local, lob_t inner)
{
  uint8_t shared[uECC_BYTES+4], iv[16], hash[32], csid = 0x1a;
  lob_t outer;
  size_t inner_len;

  outer = lob_new();
  lob_head(outer,&csid,1);
  inner_len = lob_len(inner);
  if(!lob_body(outer,NULL,21+4+inner_len+4)) return lob_free(outer);

  // copy in the ephemeral public key
  memcpy(outer->body, remote->ecomp, uECC_BYTES+1);

  // get the shared secret to create the iv+key for the open aes
  if(!uECC_shared_secret(remote->key, remote->esecret, shared)) return lob_free(outer);
  e3x_hash(shared,uECC_BYTES,hash);
  fold1(hash,hash);
  memset(iv,0,16);
  memcpy(iv,&(remote->seq),4);
  remote->seq++; // increment seq after every use
  memcpy(outer->body+21,iv,4); // send along the used IV

  // encrypt the inner into the outer
  aes_128_ctr(hash,inner_len,iv,lob_raw(inner),outer->body+21+4);

  // generate secret for hmac
  if(!uECC_shared_secret(remote->key, local->secret, shared)) return lob_free(outer);
  memcpy(shared+uECC_BYTES,outer->body+21,4); // use the IV too

  hmac_256(shared,uECC_BYTES+4,outer->body,21+4+inner_len,hash);
  fold3(hash,outer->body+21+4+inner_len); // write into last 4 bytes

  return outer;
}
示例#6
0
文件: cs1c.c 项目: mathias/telehash-c
local_t local_new(lob_t keys, lob_t secrets)
{
  local_t local = NULL;
  lob_t key, secret;

  if(!keys) keys = lob_linked(secrets); // for convenience
  key = lob_get_base32(keys,"1c");
  if(!key) return LOG("invalid key");

  secret = lob_get_base32(secrets,"1c");
  if(!secret) return LOG("invalid secret");

  if(key->body_len == COMP_BYTES && secret->body_len == SECRET_BYTES)
  {
    if((local = malloc(sizeof(struct local_struct))))
    {
      memset(local,0,sizeof (struct local_struct));

      // copy in key/secret data
      uECC_decompress(key->body,local->key, curve);
      memcpy(local->secret,secret->body,secret->body_len);

    }else{
      LOG("OOM");
    }
    
  }else{
    LOG("invalid sizes key %d=%d secret %d=%d",key->body_len,COMP_BYTES,secret->body_len,SECRET_BYTES);
  }

  lob_free(key);
  lob_free(secret);

  return local;
}
示例#7
0
// process an incoming handshake
link_t link_receive_handshake(link_t link, lob_t inner)
{
  uint32_t out, at, err;
  uint8_t csid = 0;
  lob_t outer = lob_linked(inner);

  if(!link || !inner || !outer) return LOG("bad args");

  // inner/link must be validated by caller already, we just load if missing
  if(!link->key)
  {
    util_unhex(lob_get(inner, "csid"), 2, &csid);
    if(!link_load(link, csid, inner))
    {
      lob_free(inner);
      return LOG("load key failed for %s %u %s",hashname_short(link->id),csid,util_hex(inner->body,inner->body_len,NULL));
    }
  }

  if((err = e3x_exchange_verify(link->x,outer)))
  {
    lob_free(inner);
    return LOG("handshake verification fail: %d",err);
  }

  out = e3x_exchange_out(link->x,0);
  at = lob_get_uint(inner,"at");
  link_t ready = link_up(link);

  // if bad at, always send current handshake
  if(e3x_exchange_in(link->x, at) < out)
  {
    LOG("old handshake: %s (%d,%d,%d)",lob_json(inner),at,out);
    link_sync(link);
    lob_free(inner);
    return link;
  }

  // try to sync ephemeral key
  if(!e3x_exchange_sync(link->x,outer))
  {
    lob_free(inner);
    return LOG("sync failed");
  }

  // we may need to re-sync
  if(out != e3x_exchange_out(link->x,0)) link_sync(link);

  // notify of ready state change
  if(!ready && link_up(link))
  {
    LOG("link ready");
    mesh_link(link->mesh, link);
  }

  link->handshake = lob_free(link->handshake);
  link->handshake = inner;
  return link;
}
示例#8
0
// ack/miss only base packet
lob_t e3x_channel_oob(e3x_channel_t c)
{
  lob_t ret, cur;
  char *miss;
  uint32_t seq, last, delta;
  size_t len;
  if(!c) return NULL;

  ret = lob_new();
  lob_set_uint(ret,"c",c->id);
  
  if(!c->seq) return ret;
  
  // check for ack/miss
  if(c->ack != c->acked)
  {
    lob_set_uint(ret,"ack",c->ack);

    // also check to include misses
    cur = c->in;
    last = c->ack;
    if(cur && (cur->id - last) != 1)
    {
      // I'm so tired of strings in c
      len = 2;
      if(!(miss = malloc(len))) return lob_free(ret);
      len = (size_t)snprintf(miss,len,"[");
      for(seq=c->ack+1; cur; seq++)
      {
//        LOG("ack %d seq %d last %d cur %d",c->ack,seq,last,cur->id);
        // if we have this seq, skip to next packet
        if(cur->id <= seq)
        {
          cur = cur->next;
          continue;
        }
        // insert this missing seq delta
        delta = seq - last;
        last = seq;
        len += (size_t)snprintf(NULL, 0, "%u,", delta) + 1;
        if(!(miss = realloc(miss, len))) return lob_free(ret);
        sprintf(miss+strlen(miss),"%u,", delta);
      }
      // add current window at the end
      delta = 100; // TODO calculate this from actual space avail
      len += (size_t)snprintf(NULL, 0, "%u]", delta) + 1;
      if(!(miss = realloc(miss, len))) return lob_free(ret);
      sprintf(miss+strlen(miss),"%u]", delta);
      lob_set_raw(ret,"miss",4,miss,strlen(miss));
    }

    c->acked = c->ack;
  }
  
  return ret;
}
示例#9
0
// process an incoming handshake
link_t link_receive_handshake(link_t link, lob_t inner, pipe_t pipe)
{
  link_t ready;
  uint32_t out, err;
  seen_t seen;
  uint8_t csid = 0;
  char *hexid;
  lob_t attached, outer = lob_linked(inner);

  if(!link || !inner || !outer) return LOG("bad args");
  hexid = lob_get(inner, "csid");
  if(!lob_get(link->mesh->keys, hexid)) return LOG("unsupported csid %s",hexid);
  util_unhex(hexid, 2, &csid);
  attached = lob_parse(inner->body, inner->body_len);
  if(!link->key && link_key(link->mesh, attached, csid) != link) return LOG("invalid/mismatch link handshake");
  if((err = e3x_exchange_verify(link->x,outer))) return LOG("handshake verification fail: %d",err);

  out = e3x_exchange_out(link->x,0);
  ready = link_up(link);

  // if bad at, always send current handshake
  if(e3x_exchange_in(link->x, lob_get_uint(inner,"at")) < out)
  {
    LOG("old/bad at: %s (%d,%d,%d)",lob_json(inner),lob_get_int(inner,"at"),e3x_exchange_in(link->x,0),e3x_exchange_out(link->x,0));
    // just reset pipe seen and call link_sync to resend handshake
    for(seen = link->pipes;pipe && seen;seen = seen->next) if(seen->pipe == pipe) seen->at = 0;
    lob_free(link_sync(link));
    return NULL;
  }

  // trust/add this pipe
  if(pipe) link_pipe(link,pipe);

  // try to sync ephemeral key
  if(!e3x_exchange_sync(link->x,outer)) return LOG("sync failed");
  
  // we may need to re-sync
  if(out != e3x_exchange_out(link->x,0)) lob_free(link_sync(link));
  
  // notify of ready state change
  if(!ready && link_up(link))
  {
    LOG("link ready");
    mesh_link(link->mesh, link);
  }
  
  return link;
}
示例#10
0
lob_t ephemeral_encrypt(ephemeral_t ephem, lob_t inner)
{
  lob_t outer;
  uint8_t iv[16], hmac[32];
  size_t inner_len;

  outer = lob_new();
  inner_len = lob_len(inner);
  if(!lob_body(outer,NULL,16+4+inner_len+4)) return lob_free(outer);

  // copy in token and create/copy iv
  memcpy(outer->body,ephem->token,16);
  memset(iv,0,16);
  memcpy(iv,&(ephem->seq),4);
  ephem->seq++;
  memcpy(outer->body+16,iv,4);

  // encrypt full inner into the outer
  aes_128_ctr(ephem->enckey,inner_len,iv,lob_raw(inner),outer->body+16+4);

  // generate mac key and mac the ciphertext
  memcpy(hmac,ephem->enckey,16);
  memcpy(hmac+16,iv,4);
  hmac_256(hmac,16+4,outer->body+16+4,inner_len,hmac);
  fold3(hmac,outer->body+16+4+inner_len);

  return outer;
}
示例#11
0
文件: link.c 项目: fd/telehash-c
// load in the key to existing link
link_t link_load(link_t link, uint8_t csid, lob_t key)
{
  char hex[3];
  lob_t copy;

  if(!link || !csid || !key) return LOG("bad args");
  if(link->x) return link;

  LOG("adding %x key to link %s",csid,link->id->hashname);
  
  // key must be bin
  if(key->body_len)
  {
    copy = lob_copy(key);
  }else{
    util_hex(&csid,1,hex);
    copy = lob_get_base32(key,hex);
  }
  link->x = exchange3_new(link->mesh->self, csid, copy);
  if(!link->x)
  {
    lob_free(copy);
    return LOG("invalid %x key %d %s",csid,key->body_len,lob_json(key));
  }

  link->csid = csid;
  link->key = copy;
  // route packets to this token
  util_hex(exchange3_token(link->x),16,link->token);
  xht_set(link->mesh->index,link->token,link);
  exchange3_out(link->x, platform_seconds());
  LOG("delivering session token %s to %s",link->token,link->id->hashname);

  return link;
}
示例#12
0
// add a pipe to this link if not yet
link_t link_pipe(link_t link, pipe_t pipe)
{
  seen_t seen;

  if(!link || !pipe) return LOG("bad args");

  // see if we've seen it already
  for(seen = link->pipes; seen; seen = seen->next)
  {
    if(seen->pipe == pipe) return link;
  }

  // add this pipe to this link
  LOG("adding pipe %s",pipe->id);
  if(!(seen = malloc(sizeof (struct seen_struct)))) return NULL;
  memset(seen,0,sizeof (struct seen_struct));
  seen->pipe = pipe;
  seen->next = link->pipes;
  link->pipes = seen;
  
  // make sure it gets sync'd
  lob_free(link_sync(link));

  return link;
}
示例#13
0
文件: link.c 项目: fd/telehash-c
// process a decrypted channel packet
link_t link_receive(link_t link, lob_t inner, pipe_t pipe)
{
  chan_t chan;

  if(!link || !inner) return LOG("bad args");

  // see if existing channel and send there
  if((chan = xht_get(link->index, lob_get(inner,"c"))))
  {
    if(channel3_receive(chan->c3, inner)) return LOG("channel receive error, dropping %s",lob_json(inner));
    link_pipe(link,pipe); // we trust the pipe at this point
    if(chan->handle) chan->handle(link, chan->c3, chan->arg);
    // check if there's any packets to be sent back
    return link_flush(link, chan->c3, NULL);
  }

  // if it's an open, validate and fire event
  if(!lob_get(inner,"type")) return LOG("invalid channel open, no type %s",lob_json(inner));
  if(!exchange3_cid(link->x, inner)) return LOG("invalid channel open id %s",lob_json(inner));
  link_pipe(link,pipe); // we trust the pipe at this point
  inner = mesh_open(link->mesh,link,inner);
  if(inner)
  {
   LOG("unhandled channel open %s",lob_json(inner));
   lob_free(inner);
   return NULL;
  }
  
  return link;
}
示例#14
0
link_t mesh_add(mesh_t mesh, lob_t json, pipe_t pipe)
{
  link_t link;
  lob_t keys, paths;
  uint8_t csid;

  if(!mesh || !json) return LOG("bad args");
  LOG("mesh add %s",lob_json(json));
  link = link_get(mesh, hashname_vchar(lob_get(json,"hashname")));
  keys = lob_get_json(json,"keys");
  paths = lob_get_array(json,"paths");
  if(!link) link = link_keys(mesh, keys);
  if(!link) LOG("no hashname");
  
  LOG("loading keys/paths");
  if(keys && (csid = hashname_id(mesh->keys,keys))) link_load(link, csid, keys);

  // handle any pipe/paths
  if(pipe) link_pipe(link, pipe);
  lob_t path;
  for(path=paths;path;path = lob_next(path)) link_path(link,path);
  
  lob_free(keys);
  lob_freeall(paths);

  return link;
}
示例#15
0
int main(int argc, char **argv)
{
  fail_unless(e3x_init(NULL) == 0);
  lob_t id = e3x_generate();
  fail_unless(id);

  e3x_self_t self = e3x_self_new(id,NULL);
  fail_unless(self);
  
  int i, count = 0;
  for(i = 0; i < CS_MAX; i++)
  {
    if(!self->locals[i]) continue;
    LOG("self testing CS %d",i);
    count++;
    fail_unless(self->locals[i]);
    fail_unless(self->keys[i]);
    fail_unless(self->keys[i]->body_len);
    fail_unless(lob_get(self->keys[i],"key"));
    fail_unless(lob_get(self->keys[i],"hash"));
    fail_unless(strlen(lob_get(self->keys[i],"hash")) == 52);
  }

  fail_unless(count);
  e3x_self_free(self);
  lob_free(id);

  return 0;
}
示例#16
0
// this will set the default inactivity timeout using this event timer and our uid
uint32_t e3x_channel_timeout(e3x_channel_t c, e3x_event_t ev, uint32_t timeout)
{
  if(!c) return 0;

  // un-set any
  if(ev != c->ev)
  {
    // cancel and clearn any previous timer state
    c->timeout = 0;
    if(c->ev) e3x_event_set(c->ev,NULL,c->uid,0);
    c->ev = NULL;
    lob_free(c->timer);
    c->timer = NULL;
  }
  
  // no event manager, no timeouts
  if(!ev) return 0;
  
  // no timeout, just return how much time is left
  if(!timeout) return _time_left(c);

  // add/update new timeout
  c->tsince = util_sys_seconds(); // start timer now
  c->timeout = timeout;
  c->ev = ev;
  c->timer = lob_new();
  lob_set_uint(c->timer,"c",c->id);
  lob_set(c->timer, "id", c->uid);
  lob_set(c->timer, "err", "timeout");
  e3x_event_set(c->ev, c->timer, lob_get(c->timer, "id"), timeout*1000); // ms in the future
  return _time_left(c);
}
示例#17
0
// deliver this packet
link_t link_send(link_t link, lob_t outer)
{
  if(!outer) return LOG_INFO("send packet missing");
  if(!link || !link->send_cb)
  {
    lob_free(outer);
    return LOG_WARN("no network");
  }

  if(!link->send_cb(link, outer, link->send_arg))
  {
    lob_free(outer);
    return LOG_WARN("delivery failed");
  }

  return link;
}
示例#18
0
文件: tcp4.c 项目: fd/telehash-c
void net_tcp4_free(net_tcp4_t net)
{
  if(!net) return;
  close(net->server);
  xht_free(net->pipes);
  lob_free(net->path);
  free(net);
  return;
}
示例#19
0
// creates a new mesh identity, returns secrets
lob_t mesh_generate(mesh_t mesh)
{
  lob_t secrets;
  if(!mesh || mesh->self) return LOG_ERROR("invalid mesh");
  secrets = e3x_generate();
  if(!secrets) return LOG_ERROR("failed to generate %s",e3x_err());
  if(mesh_load(mesh, secrets, lob_linked(secrets))) return lob_free(secrets);
  return secrets;
}
示例#20
0
void pair_send(pipe_t pipe, lob_t packet, link_t link)
{
  net_loopback_t pair = (net_loopback_t)pipe->arg;
  if(!pair || !packet || !link) return;
  LOG("pair pipe from %s",link->id->hashname);
  if(link->mesh == pair->a) mesh_receive(pair->b,packet,pipe);
  else if(link->mesh == pair->b) mesh_receive(pair->a,packet,pipe);
  else lob_free(packet);
}
示例#21
0
int main(int argc, char **argv)
{
  lob_t opts = lob_new();
  fail_unless(e3x_init(opts) == 0);
  fail_unless(!lob_get(opts,"err"));
  fail_unless(!e3x_err());
  lob_free(opts);
  return 0;
}
示例#22
0
lob_t link_handshake(link_t link)
{
  if(!link) return NULL;
  if(!link->x) return LOG_DEBUG("no exchange");

  LOG_DEBUG("generating a new handshake in %lu out %lu",link->x->in,link->x->out);
  lob_t handshake = lob_copy(link->mesh->handshake);
  lob_t tmp = hashname_im(link->mesh->keys, link->csid);
  lob_body(handshake, lob_raw(tmp), lob_len(tmp));
  lob_free(tmp);

  // encrypt it
  tmp = handshake;
  handshake = e3x_exchange_handshake(link->x, tmp);
  lob_free(tmp);

  return handshake;
}
示例#23
0
lob_t link_handshakes(link_t link)
{
  uint32_t i;
  uint8_t csid;
  char *key;
  lob_t tmp, hs = NULL, handshakes = NULL;
  if(!link) return NULL;
  
  // no keys means we have to generate a handshake for each key
  if(!link->x)
  {
    for(i=0;(key = lob_get_index(link->mesh->keys,i));i+=2)
    {
      util_unhex(key,2,&csid);
      hs = lob_new();
      tmp = hashname_im(link->mesh->keys, csid);
      lob_body(hs, lob_raw(tmp), lob_len(tmp));
      lob_free(tmp);
      handshakes = lob_link(hs, handshakes);
    }
  }else{ // generate one just for this csid
    handshakes = lob_new();
    tmp = hashname_im(link->mesh->keys, link->csid);
    lob_body(handshakes, lob_raw(tmp), lob_len(tmp));
    lob_free(tmp);
  }

  // add any custom per-link
  for(hs = link->handshakes; hs; hs = lob_linked(hs)) handshakes = lob_link(lob_copy(hs), handshakes);

  // add any mesh-wide handshakes
  for(hs = link->mesh->handshakes; hs; hs = lob_linked(hs)) handshakes = lob_link(lob_copy(hs), handshakes);
  
  // encrypt them if we can
  if(link->x)
  {
    tmp = handshakes;
    handshakes = NULL;
    for(hs = tmp; hs; hs = lob_linked(hs)) handshakes = lob_link(e3x_exchange_handshake(link->x, hs), handshakes);
    lob_free(tmp);
  }

  return handshakes;
}
示例#24
0
// return >0 if this alg is supported
uint8_t jwt_alg(char *alg)
{
  uint8_t err;
  lob_t test = lob_new();
  lob_set(test,"alg",alg);
  // TODO refactor how this is checked
  err = e3x_exchange_validate(NULL, test, NULL, (uint8_t*)"x", 1);
  lob_free(test);
  return (err == 1) ? 0 : 1;
}
示例#25
0
pipe_t pipe_free(pipe_t p)
{
  free(p->type);
  if(p->id) free(p->id);
  if(p->path) lob_free(p->path);
  if(p->notify) LOG("pipe free'd leaking notifications");
  if(p->free) p->free(p);
  free(p);
  return NULL;
}
示例#26
0
mesh_t util_links(mesh_t mesh, char *file)
{
  lob_t links = util_fjson(file);
  if(!links) return NULL;

  // TODO iterate and link

  lob_free(links);

  return mesh;
}
示例#27
0
hashname_t hashname_keys(lob_t keys)
{
  hashname_t hn;
  lob_t im;

  if(!keys) return LOG("bad args");
  im = hashname_im(keys,0);
  hn = hashname_key(im,0);
  lob_free(im);
  return hn;
}
示例#28
0
// process a decrypted channel packet
link_t link_receive(link_t link, lob_t inner)
{
  chan_t c;

  if(!link || !inner) return LOG("bad args");

  LOG("<-- %d",lob_get_int(inner,"c"));
  // see if existing channel and send there
  if((c = link_chan_get(link, lob_get_int(inner,"c"))))
  {
    LOG("found chan");
    // consume inner
    chan_receive(c, inner);
    // process any changes
    link->chans = link_process_chan(link->chans, 0);
    return link;
  }

  // if it's an open, validate and fire event
  if(!lob_get(inner,"type"))
  {
    LOG("invalid channel open, no type %s",lob_json(inner));
    lob_free(inner);
    return NULL;
  }
  if(!e3x_exchange_cid(link->x, inner))
  {
    LOG("invalid channel open id %s",lob_json(inner));
    lob_free(inner);
    return NULL;
  }
  inner = mesh_open(link->mesh,link,inner);
  if(inner)
  {
    LOG("unhandled channel open %s",lob_json(inner));
    lob_free(inner);
    return NULL;
  }

  return link;
}
示例#29
0
void e3x_channel_free(e3x_channel_t c)
{
  if(!c) return;
  // cancel timeouts
  e3x_channel_timeout(c,NULL,0);
  // free cached packet
  lob_free(c->open);
  // free any other queued packets
  lob_freeall(c->in);
  lob_freeall(c->out);
  free(c);
}
示例#30
0
link_t link_get_keys(mesh_t mesh, lob_t keys)
{
  uint8_t csid;

  if(!mesh || !keys) return LOG("invalid args");
  csid = hashname_id(mesh->keys,keys);
  if(!csid) return LOG("no supported key");
  lob_t key = hashname_im(keys,csid);
  link_t ret = link_get_key(mesh, key, csid);
  lob_free(key);
  return ret;
}