Exemple #1
0
void recv_data(int len) {
    static i32 i;
    static u32 buffer[4];
    const __builtin_quad *b = (__builtin_quad *)buffer;
    i32 tout;
    
    while (len >= 4) {
        tout = 0x1000;
        buffer[i] = 
                (u32)(RECEIVE_NETWORK_B() & 0xFF) << 24 |
                (u32)(RECEIVE_NETWORK_B() & 0xFF) << 16 |
                (u32)(RECEIVE_NETWORK_B() & 0xFF) <<  8 |
                (u32)(RECEIVE_NETWORK_B() & 0xFF);
        
        i = (i + 1) % 4;
        
        if (i == 0) {
            while (!link_ready() && --tout) {
                asm("nop;nop;nop;nop;;");
            }
            if (tout) {
                link_send(b);
            }
        }
        
        if (tout) {
            len -= 4;
        }
        else {
            len  = 0;
        }
        
    }
    
}
Exemple #2
0
// send current handshake
link_t link_sync(link_t link)
{
  if(!link) return LOG("bad args");
  if(!link->x) return LOG("no exchange");
  if(!link->send_cb) return LOG("no network");

  return link_send(link, link_handshake(link));
}
Exemple #3
0
// process any outgoing packets for this channel, optionally send given packet too
link_t link_flush(link_t link, channel3_t c3, lob_t inner)
{
  if(!link || !c3) return LOG("bad args");
  
  if(inner) channel3_send(c3, inner);

  while((inner = channel3_sending(c3)))
  {
    link_send(link, exchange3_send(link->x, inner));
    lob_free(inner);
  }
  
  // TODO if channel is now ended, remove from link->index

  return link;
}
Exemple #4
0
// encrypt and send this one packet on this pipe
link_t link_direct(link_t link, lob_t inner)
{
  if(!link || !inner) return LOG("bad args");
  if(!link->send_cb)
  {
    LOG_WARN("no network, dropping %s",lob_json(inner));
    return NULL;
  }

  // add an outgoing cid if none set
  if(!lob_get_int(inner,"c")) lob_set_uint(inner,"c",e3x_exchange_cid(link->x, NULL));

  lob_t outer = e3x_exchange_send(link->x, inner);
  lob_free(inner);

  return link_send(link, outer);
}
Exemple #5
0
// process any outgoing packets for this channel, optionally send given packet too
link_t link_flush(link_t link, e3x_channel_t c3, lob_t inner)
{
  if(!link || !c3) return LOG("bad args");
  
  if(inner) e3x_channel_send(c3, inner);

  while((inner = e3x_channel_sending(c3)))
  {
    LOG("\t--> %s",lob_json(inner));
    link_send(link, e3x_exchange_send(link->x, inner));
    lob_free(inner);
  }
  
  // TODO if channel is now ended, remove from link->index

  return link;
}
/*thread que recebe da camada de baixo*/
PRIVATE void *internalsend(void *param)
{
    int isfragmentable;
    int mtu;
    uint16_t count_id = 0;
    wait_list_item_t intern_list_cons;
    offsetlst_t *head = NULL,*aux;
    datagram_t *data_send = ALLOC(datagram_t, sizeof(datagram_t));
    byte *buffer;
    while(TRUE)
    {
        intern_list_cons = wait_list_remove();
        //getmtu do destino
        mtu = getmtu(num_global, intern_list_cons.first_dest_link);
        //protocolo = 1 utilizado pelo transp ou protocolo = 0 utilizado pela tab de rotas
        if(intern_list_cons.protocol == 1 || intern_list_cons.protocol ==  0)
        {
            isfragmentable = fragpack(&head,intern_list_cons.data,intern_list_cons.size,mtu,intern_list_cons.offset);
            LOG("dest1 %d", intern_list_cons.dest);
            //sabe que é apenas dados
            if(isfragmentable == 0)
            {
                //nao precisou fragmentar
                data_send->size = intern_list_cons.size;
                data_send->id = count_id;
                data_send->frag = intern_list_cons.offset;
                data_send->protocol = intern_list_cons.protocol;
                data_send->ttl = intern_list_cons.ttl;
                data_send->dest = intern_list_cons.dest;
                data_send->src = intern_list_cons.src;
                data_send->data = ALLOC(byte, data_send->size);
                memcpy(data_send->data, intern_list_cons.data, data_send->size);
                buffer = ALLOC(byte, data_send->size + NET_HEADER_SIZE);
                buildsenddatagram(buffer,data_send);
                free(data_send->data);

                if(count_id <= 65535)
                    count_id++;
                else
                    count_id = 0;

                LOG("enviando para enlace");
                link_send(intern_list_cons.first_dest_link, buffer, data_send->size + NET_HEADER_SIZE);
                //free(data_send); ???

            }
            else
            {LOG("frag para enlace");
                while(head != NULL)
                {LOG("head para enlace");
                    //precisa fragmentar
                    data_send->size = head->datagram->size;
                    data_send->id = count_id;
                    data_send->frag = head->datagram->frag;
                    data_send->protocol = intern_list_cons.protocol;
                    data_send->ttl = intern_list_cons.ttl;
                    data_send->dest = intern_list_cons.dest;
                    LOG("dest %d", data_send->dest);
                    data_send->src = intern_list_cons.src;
                    data_send->data = ALLOC(byte, head->datagram->size);
                    memcpy(data_send->data, head->datagram->data, head->datagram->size);
                    LOG("enviando data %s", data_send->data);
                    buffer = ALLOC(byte, data_send->size + NET_HEADER_SIZE);
                    buildsenddatagram(buffer,data_send);
                    free(data_send->data);
                    link_send(intern_list_cons.first_dest_link, buffer, data_send->size + NET_HEADER_SIZE);
                    //anda com a lista
                    aux = head;

                    head = head->next;

                    free(aux);
                }
                LOG("fim para enlace");
                if(count_id <= 65535)
                    count_id++;
                else
                    count_id = 0;
            }
        }
        //protocolo = 2 , utilizado pelo repasse
        else
        {
            if(intern_list_cons.protocol == 2)
            {
                isfragmentable = fragpack2(&head,intern_list_cons.data,intern_list_cons.size,mtu,intern_list_cons.offset);
                
                if(isfragmentable == 0)
                {
                    //nao precisou fragmentar
                    data_send->size = intern_list_cons.size;
                    data_send->id = intern_list_cons.id;
                    data_send->frag = intern_list_cons.offset;
                    data_send->protocol = intern_list_cons.protocol;
                    data_send->ttl = intern_list_cons.ttl;
                    data_send->dest = intern_list_cons.dest;
                    data_send->src = intern_list_cons.src;
                    data_send->data = ALLOC(byte, data_send->size);
                    memcpy(data_send->data, intern_list_cons.data, data_send->size);
                    buffer = ALLOC(byte, data_send->size + NET_HEADER_SIZE);
                    buildsenddatagram(buffer,data_send);
                    free(data_send->data);
                    LOG("enviando para enlace");
                    link_send(intern_list_cons.first_dest_link, buffer, data_send->size + NET_HEADER_SIZE);
                    //free(data_send); ???
                }
                else
                {
                    while(head != NULL)
                    {
                        //precisa fragmentar
                        data_send->size = head->datagram->size;
                        data_send->id = intern_list_cons.id;
                        data_send->frag = head->datagram->frag;
                        data_send->protocol = intern_list_cons.protocol;
                        data_send->ttl = intern_list_cons.ttl;
                        data_send->dest = intern_list_cons.dest;
                        data_send->src = intern_list_cons.src;
                        data_send->data = ALLOC(byte, head->datagram->size);
                        memcpy(data_send->data, head->datagram->data, head->datagram->size);
                        
                        buffer = ALLOC(byte, data_send->size + NET_HEADER_SIZE);
                        buildsenddatagram(buffer,data_send);
                        free(data_send->data);
                        link_send(intern_list_cons.first_dest_link, buffer, data_send->size + NET_HEADER_SIZE);
                        //anda com a lista
                        aux = head;

                        head = head->next;

                        free(aux);
                    }
                    
                }
            }
        } 
    }
}
Exemple #7
0
/* Send a sequence of bytes over the virtual link
 * On error: Throws a Byte Exception */
void link_send_bytes(CPU_t *cpu, void *data, size_t length) {
	size_t i;
	for (i = 0; i < length; i++)
		link_send(cpu, ((u_char*) data)[i]);
}
Exemple #8
0
// processes incoming packet, it will take ownership of p
link_t mesh_receive(mesh_t mesh, lob_t outer, pipe_t pipe)
{
  lob_t inner;
  link_t link;
  char token[17];
  hashname_t id;

  if(!mesh || !outer || !pipe) return LOG("bad args");
  
  LOG("mesh receiving %s to %s via pipe %s",outer->head_len?"handshake":"channel",hashname_short(mesh->id),pipe->id);

  // process handshakes
  if(outer->head_len == 1)
  {
    inner = e3x_self_decrypt(mesh->self, outer);
    if(!inner)
    {
      LOG("%02x handshake failed %s",outer->head[0],e3x_err());
      lob_free(outer);
      return NULL;
    }
    
    // couple the two together, inner->outer
    lob_link(inner,outer);

    // set the unique id string based on some of the first 16 (routing token) bytes in the body
    base32_encode(outer->body,10,token,17);
    lob_set(inner,"id",token);

    // process the handshake
    return mesh_receive_handshake(mesh, inner, pipe);
  }

  // handle channel packets
  if(outer->head_len == 0)
  {
    if(outer->body_len < 16)
    {
      LOG("packet too small %d",outer->body_len);
      lob_free(outer);
      return NULL;
    }
    
    route_t route;
    for(route = mesh->routes;route;route = route->next) if(memcmp(route->token,outer->body,8) == 0) break;
    link = route ? route->link : NULL;
    if(!link)
    {
      LOG("dropping, no link for token %s",util_hex(outer->body,16,NULL));
      lob_free(outer);
      return NULL;
    }
    
    // forward packet
    if(!route->flag)
    {
      LOG("forwarding route token %s via %s len %d",util_hex(route->token,8,NULL),hashname_short(link->id),lob_len(outer));
      return link_send(link, outer);
    }
    
    inner = e3x_exchange_receive(link->x, outer);
    lob_free(outer);
    if(!inner) return LOG("channel decryption fail for link %s %s",hashname_short(link->id),e3x_err());
    
    LOG("channel packet %d bytes from %s",lob_len(inner),hashname_short(link->id));
    return link_receive(link,inner,pipe);
    
  }

  // transform incoming bare link json format into handshake for discovery
  if((inner = lob_get_json(outer,"keys")))
  {
    if((id = hashname_vkeys(inner)))
    {
      lob_set(outer,"hashname",hashname_char(id));
      lob_set_int(outer,"at",0);
      lob_set(outer,"type","link");
      LOG("bare incoming link json being discovered %s",lob_json(outer));
    }
    lob_free(inner);
  }
  
  // run everything else through discovery, usually plain handshakes
  mesh_discover(mesh, outer, pipe);
  link = mesh_linked(mesh, lob_get(outer,"hashname"), 0);
  lob_free(outer);

  return link;
}