Пример #1
0
// display pmem pool
void pmemalloc_display() {
  struct clump* clp;
  size_t sz;
  size_t prev_sz;
  int state;
  clp = (struct clump *)ABS_PTR((struct clump *) PMEM_CLUMP_OFFSET);

  fprintf(stdout,
          "----------------------------------------------------------\n");
  while (1) {
    sz = clp->size & ~PMEM_STATE_MASK;
    prev_sz = clp->prevsize;
    state = clp->size & PMEM_STATE_MASK;

    fprintf(stdout, "%lu (%d)(%p)(%lu) -> ", sz, state, (struct clump *)REL_PTR(clp), prev_sz);

    if (clp->size == 0)
      break;

    clp = (struct clump *) ((uintptr_t) clp + sz);
  }

  fprintf(stdout, "\n");
  fprintf(stdout,
          "----------------------------------------------------------\n");

  fflush(stdout);
}
Пример #2
0
/**
 * Returns how many bytes in *where have been used
 *
 * TODO this is little shitty, someone should unify all the param flavours 
 * to a sigle universal type of parameter (to_param,param,disposition_param)
 * the way is done here, at least, we dont have the parameter-hanling code spread all around.
 */
int encode_parameters(unsigned char *where,void *pars,char *hdrstart,void *_body,char to)
{
   struct param *parametro,*params;
   struct to_param *toparam,*toparams;
   struct disposition_param *dparam,*dparams;
   struct via_param *vparam,*vparams;
   struct via_body *vbody;
   struct to_body *tbody;
   char *mylittlepointer,*paramstart; 
   int i,j,paramlen;
   i=0;
   if(!pars)
      return 0;
   if(to=='t'){
      toparams=(struct to_param*)pars;
      tbody=(struct to_body*)_body;
      for(toparam=toparams;toparam;toparam=toparam->next){
	 where[i++]=(unsigned char)(toparam->name.s-hdrstart);
	 if(toparam->value.s)
	    mylittlepointer=toparam->value.s;
	 else
	    if(toparam->next)
	       mylittlepointer=toparam->next->name.s;
	    else
	       mylittlepointer=toparam->name.s+toparam->name.len+1;
	 where[i++]=(unsigned char)(mylittlepointer-hdrstart);
      }
      if((toparam=tbody->last_param)){
	 if(toparam->value.s)
	    mylittlepointer=toparam->value.s+toparam->value.len;
	 else
	    mylittlepointer=toparam->name.s+toparam->name.len;
	 where[i++]=(unsigned char)(mylittlepointer-hdrstart+1);
      }
      return i;
   }else if(to=='n'){
      params=(struct param*)pars;
      for(parametro=reverseParameters(params);parametro;parametro=parametro->next){
	 where[i++]=(unsigned char)(parametro->name.s-hdrstart);
	 if(parametro->body.s)
	    mylittlepointer=parametro->body.s;
	 else
	    if(parametro->next)
	       mylittlepointer=parametro->next->name.s;
	    else
	       mylittlepointer=parametro->name.s+parametro->name.len+1;
	 where[i++]=(unsigned char)(mylittlepointer-hdrstart);
      }
      /*look for the last parameter*/
      /*WARNING the ** parameters are in reversed order !!! */
      /*TODO parameter encoding logic should be moved to a specific function...*/
      for(parametro=params;parametro && parametro->next;parametro=parametro->next);
      /*printf("PARAMETRO:%.*s\n",parametro->name.len,parametro->name.s);*/
      if(parametro){
	 if(parametro->body.s)
	    mylittlepointer=parametro->body.s+parametro->body.len;
	 else
	    mylittlepointer=parametro->name.s+parametro->name.len;
	 where[i++]=(unsigned char)(mylittlepointer-hdrstart+1);
      }
      return i;
   }else if(to=='d'){
      dparams=(struct disposition_param*)pars;
      for(dparam=dparams;dparam;dparam=dparam->next){
	 where[i++]=(unsigned char)(dparam->name.s-hdrstart);
	 if(dparam->body.s)
	    mylittlepointer=dparam->body.s;
	 else
	    if(dparam->next)
	       mylittlepointer=dparam->next->name.s;
	    else
	       mylittlepointer=dparam->name.s+dparam->name.len+1;
	 where[i++]=(unsigned char)(mylittlepointer-hdrstart);
      }
      /*WARNING the ** parameters are in reversed order !!! */
      /*TODO parameter encoding logic should be moved to a specific function...*/
      for(dparam=dparams;dparam && dparam->next;dparam=dparam->next);
      if(dparam){
	 if(dparam->body.s)
	    mylittlepointer=dparam->body.s+dparam->body.len;
	 else
	    mylittlepointer=dparam->name.s+dparam->name.len;
	 where[i++]=(unsigned char)(mylittlepointer-hdrstart+1);
      }
      return i;
   }else if(to=='v'){
      vparams=(struct via_param*)pars;
      vbody=(struct via_body*)_body;
      for(vparam=vparams;vparam;vparam=vparam->next){
	 where[i++]=REL_PTR(hdrstart,vparam->name.s);
	 if(vparam->value.s)
	    mylittlepointer=vparam->value.s;
	 else
	    if(vparam->next)
	       mylittlepointer=vparam->next->name.s;
	    else
	       mylittlepointer=vparam->name.s+vparam->name.len+1;
	 where[i++]=REL_PTR(hdrstart,mylittlepointer);
      }
      if((vparam=vbody->last_param)){
	 if(vparam->value.s)
	    mylittlepointer=vparam->value.s+vparam->value.len;
	 else
	    mylittlepointer=vparam->name.s+vparam->name.len;
	 where[i++]=REL_PTR(hdrstart,mylittlepointer+1);
      }
      return i;
   }else if(to=='u'){
      paramlen=*((int*)_body);
      paramstart=(char *)pars;
      j=i=0;
      if(paramstart==0 || paramlen==0)
	 return 0;
      /*the first parameter start index, I suppose paramstart points to the first
       letter of the first parameter: sip:[email protected];param1=true;param2=false
                                     paramstart points to __^                      
       each parameter is codified with its {param_name_start_idx,[param_value_start_idx|next_param_start_idx]} */
      where[j++]=paramstart-hdrstart;
      while(i<paramlen){
	 i++;
	 if(paramstart[i]==';'){/*no '=' found !*/
	    where[j++]=(unsigned char)(&paramstart[i+1]-hdrstart);
	    where[j++]=(unsigned char)(&paramstart[i+1]-hdrstart);
	 }
	 if(paramstart[i]=='='){/* '=' found, look for the next ';' and let 'i' pointing to it*/
	    where[j++]=(unsigned char)(&paramstart[i+1]-hdrstart);
	    for(;i<paramlen&&paramstart[i]!=';';i++);
	    if(paramstart[i]==';')
	       where[j++]=(unsigned char)(&paramstart[i+1]-hdrstart);
	 }
      }
      where[j++]=(unsigned char)(&paramstart[i+1]-hdrstart);
      if(j%2 == 0)/*this is because maybe the LAST parameter doesn't have an '='*/
	 where[j++]=(unsigned char)(&paramstart[i+1]-hdrstart);
      return j;
   }
   return 0;
}
Пример #3
0
/*The XURI is one of the most important parts in SEAS, as
 * most of the SIP MESSAGE structured headers (that is,
 * headers which have a well-specified body construction)
 * use the URI as the body (ie. via, route, record-route,
 * contact, from, to, RURI)
 *
 * the XURI is a codified structure of flags and pointers
 * that ease the parsing of the URI string.
 *
 * 1: The first byte of the structure, is a
 * HEADER_START-based pointer to the beginning of the URI
 * (including the "sip:").  
 * 1: The next byte is the length of the uri, so URIMAX 
 * is 256 (enough...) 
 * 2: Flags specifying the parts that are present in the URI
 *
 * as follows:
 * 	1: first byte
 * 		SIP_OR_TEL_F	0x01 it is SIP or TEL uri.
 *		SECURE_F	0x02 it is secure or not (SIPS,TELS)
 *		USER_F		0x04 it as a user part (user@host)
 *		PASSWORD_F	0x08 it has a password part
 *		HOST_F		0x10 it has a host part
 *		PORT_F		0x20 it has a port part
 *		PARAMETERS_F	0x40 it has a port part
 *		HEADERS_F	0x80 it has a port part
 *	1: second byte
 *		TRANSPORT_F	0x01 it has other parameters
 *		TTL_F		0x02 it has headers
 *		USER_F		0x04 it has the transport parameter
 *		METHOD_F	0x08 it has the ttl parameter
 *		MADDR_F		0x10 it has the user parameter
 *		LR_F		0x20 it has the method parameter
 *
 * All the following bytes are URI_START-based pointers to
 * the fields that are present in the uri, as specified by
 * the flags. They must appear in the same order shown in
 * the flags, and only appear if the flag was set to 1.
 *
 * the end of the field, will be the place where the
 * following pointer points to, minus one (note that all the
 * fields present in a URI are preceded by 1 character, ie
 * sip[:user][:passwod][@host][:port][;param1=x][;param2=y][?hdr1=a][&hdr2=b]$p
 * it will be necessary to have a pointer at the end,
 * pointing two past the end of the uri, so that the length
 * of the last header can be computed.
 *
 * The reason to have the OTHER and HEADERS flags at the
 * beginning(just after the strictly-uri stuff), is that it
 * will be necessary to know the length of the parameters
 * section and the headers section.  
 *
 * The parameters can
 * appear in an arbitrary order, so they won't be following
 * the convention of transport-ttl-user-method-maddr-lr, so
 * we can't rely on the next pointer to compute the length
 * of the previous pointer field, as the ttl param can 
 * appear before the transport param. so the parameter 
 * pointers must have 2 bytes: pointer+length.
 *
 */
int encode_uri2(char *hdr,int hdrlen,str uri_str, struct sip_uri *uri_parsed,unsigned char *payload)
{
   int i=4,j;/* 1*pointer+1*len+2*flags*/
   unsigned int scheme;
   unsigned char flags1=0,flags2=0,uriptr;

   uriptr=REL_PTR(hdr,uri_str.s);
   if(uri_str.len>255 || uriptr>hdrlen){
      LM_ERR("uri too long, or out of the sip_msg bounds\n");
      return -1;
   }
   payload[0]=uriptr;
   payload[1]=(unsigned char)uri_str.len;
   if(uri_parsed->user.s && uri_parsed->user.len){
      flags1 |= USER_F;
      payload[i++]=REL_PTR(uri_str.s,uri_parsed->user.s);
   }
   if(uri_parsed->passwd.s && uri_parsed->passwd.len){
      flags1 |= PASSWORD_F;
      payload[i++]=REL_PTR(uri_str.s,uri_parsed->passwd.s);
   }
   if(uri_parsed->host.s && uri_parsed->host.len){
      flags1 |= HOST_F;
      payload[i++]=REL_PTR(uri_str.s,uri_parsed->host.s);
   }
   if(uri_parsed->port.s && uri_parsed->port.len){
      flags1 |= PORT_F;
      payload[i++]=REL_PTR(uri_str.s,uri_parsed->port.s);
   }
   if(uri_parsed->params.s && uri_parsed->params.len){
      flags1 |= PARAMETERS_F;
      payload[i++]=REL_PTR(uri_str.s,uri_parsed->params.s);
   }
   if(uri_parsed->headers.s && uri_parsed->headers.len){
      flags1 |= HEADERS_F;
      payload[i++]=REL_PTR(uri_str.s,uri_parsed->headers.s);
   }
   payload[i]=(unsigned char)(uri_str.len+1);
   i++;

   if(uri_parsed->transport.s && uri_parsed->transport.len){
      flags2 |= TRANSPORT_F;
      payload[i]=REL_PTR(uri_str.s,uri_parsed->transport.s);
      payload[i+1]=(unsigned char)(uri_parsed->transport.len);
      i+=2;
   }
   if(uri_parsed->ttl.s && uri_parsed->ttl.len){
      flags2 |= TTL_F;
      payload[i]=REL_PTR(uri_str.s,uri_parsed->ttl.s);
      payload[i+1]=(unsigned char)uri_parsed->ttl.len;
      i+=2;
   }
   if(uri_parsed->user_param.s && uri_parsed->user_param.len){
      flags2 |= USER_F;
      payload[i]=REL_PTR(uri_str.s,uri_parsed->user_param.s);
      payload[i+1]=(unsigned char)uri_parsed->user_param.len;
      i+=2;
   }
   if(uri_parsed->method.s && uri_parsed->method.len){
      flags2 |= METHOD_F;
      payload[i]=REL_PTR(uri_str.s,uri_parsed->method.s);
      payload[i+1]=(unsigned char)uri_parsed->method.len;
      i+=2;
   }
   if(uri_parsed->maddr.s && uri_parsed->maddr.len){
      flags2 |= MADDR_F;
      payload[i]=REL_PTR(uri_str.s,uri_parsed->maddr.s);
      payload[i+1]=(unsigned char)uri_parsed->maddr.len;
      i+=2;
   }
   if(uri_parsed->lr.s && uri_parsed->lr.len){
      flags2 |= LR_F;
      payload[i]=REL_PTR(uri_str.s,uri_parsed->lr.s);
      payload[i+1]=(unsigned char)uri_parsed->lr.len;
      i+=2;
   }
   /*in parse_uri, when there's a user=phone, the type
    * is set to TEL_URI_T, even if there's a sip: in the beginning
    * so lets check it by ourselves:
   switch(uri_parsed->type){
      case SIP_URI_T:
	 flags1 |= SIP_OR_TEL_F;
	 break;
      case SIPS_URI_T:
	 flags1 |= (SIP_OR_TEL_F|SECURE_F);
	 break;
      case TEL_URI_T:
	 break;
      case TELS_URI_T:
	 flags1 |= SECURE_F;
	 break;
      default:
	 return -1;
   }*/
#define SIP_SCH		0x3a706973
#define SIPS_SCH	0x73706973
#define TEL_SCH		0x3a6c6574
#define TELS_SCH	0x736c6574
   scheme=uri_str.s[0]+(uri_str.s[1]<<8)+(uri_str.s[2]<<16)+(uri_str.s[3]<<24);
   scheme|=0x20202020;
   if (scheme==SIP_SCH){
      flags1 |= SIP_OR_TEL_F;
   }else if(scheme==SIPS_SCH){
      if(uri_str.s[4]==':'){
	 flags1 |= (SIP_OR_TEL_F|SECURE_F);
      }else goto error;
   }else if (scheme==TEL_SCH){
      /*nothing*/
   }else if (scheme==TELS_SCH){
      if(uri_str.s[4]==':'){
	 flags1 |= SECURE_F;
      }
   }else goto error;
	
   payload[2]=flags1;
   payload[3]=flags2;
   j=i;
   i+=encode_parameters(&payload[i],uri_parsed->params.s,uri_str.s,&uri_parsed->params.len,'u');
   if(i<j)
      goto error;
   return i;
error:
   return -1;
}
Пример #4
0
// pmemalloc_reserve -- allocate memory, volatile until pmemalloc_activate()
static
void *pmemalloc_reserve(size_t size) {
  size_t nsize;

  if (size <= 64) {
    nsize = 128;
  } else {
      size_t temp = 63;
    nsize = 64 + ((size + 63) & ~temp);
  }

  //cerr<<"size :: "<<size<<" nsize :: "<<nsize<<endl;
  struct clump *clp;
  struct clump* next_clp;
  int loop = 0;
  DEBUG("size= %zu", nsize);

  if (prev_clp != NULL) {
    clp = prev_clp;
//    printf("prev_clp=%p\n", prev_clp);
  } else {
    clp = (struct clump *)ABS_PTR((struct clump *) PMEM_CLUMP_OFFSET);
  }

  DEBUG("pmp=%p clp= %p, size of clp=%d size of struct clump =%d", pmp, clp, sizeof(clp), sizeof(struct clump));

  /* first fit */
  check:  //unsigned int itr = 0;
  while (clp->size) {
//    DEBUG("************** itr :: %lu ", itr++);
    size_t sz = clp->size & ~PMEM_STATE_MASK;
    int state = clp->size & PMEM_STATE_MASK;
    DEBUG("size : %lu state : %d", sz, state);

    if (nsize <= sz) {
      if (state == PMEM_STATE_FREE) {
        void *ptr = (void *) (uintptr_t) clp + PMEM_CHUNK_SIZE
            - (uintptr_t) pmp;
        size_t leftover = sz - nsize;

        DEBUG("fit found ptr 0x%lx, leftover %lu bytes", ptr, leftover);
        if (leftover >= PMEM_CHUNK_SIZE * 2) {
          struct clump *newclp;
          newclp = (struct clump *) ((uintptr_t) clp + nsize);

          DEBUG("splitting: [0x%lx] new clump", (struct clump *)REL_PTR(newclp));
          /*
           * can go ahead and start fiddling with
           * this freely since it is in the middle
           * of a free clump until we change fields
           * in *clp.  order here is important:
           *  1. initialize new clump
           *  2. persist new clump
           *  3. initialize existing clump do list
           *  4. persist existing clump
           *  5. set new clump size, RESERVED
           *  6. persist existing clump
           */
          PM_EQU((newclp->size), (leftover | PMEM_STATE_FREE));
          PM_EQU((newclp->prevsize), (nsize));
          pmem_persist(newclp, sizeof(*newclp), 0);

          next_clp = (struct clump *) ((uintptr_t) newclp + leftover);
          PM_EQU((next_clp->prevsize), (leftover));
          pmem_persist(next_clp, sizeof(*next_clp), 0);

          PM_EQU((clp->size), (nsize | PMEM_STATE_RESERVED));
          pmem_persist(clp, sizeof(*clp), 0);

          //DEBUG("validate new clump %p", REL_PTR(newclp));
          //DEBUG("validate orig clump %p", REL_PTR(clp));
          //DEBUG("validate next clump %p", REL_PTR(next_clp));
        } else {
          DEBUG("no split required");

          PM_EQU((clp->size), (sz | PMEM_STATE_RESERVED));
          pmem_persist(clp, sizeof(*clp), 0);

          next_clp = (struct clump *) ((uintptr_t) clp + sz);
          PM_EQU((next_clp->prevsize), (sz));
          pmem_persist(next_clp, sizeof(*next_clp), 0);

          //DEBUG("validate orig clump %p", REL_PTR(clp));
          //DEBUG("validate next clump %p", REL_PTR(next_clp));
        }

        prev_clp = clp;
        return ABS_PTR(ptr);
      }
    }

    clp = (struct clump *) ((uintptr_t) clp + sz);
    DEBUG("next clump :: [0x%lx]", (struct clump *)REL_PTR(clp));
  }

  if (loop == 0) {
    DEBUG("LOOP ");
    loop = 1;
    clp = (struct clump *)ABS_PTR((struct clump *) PMEM_CLUMP_OFFSET);
    goto check;
  }
    
  printf("no free memory of size %lu available \n", nsize);
  printf("Increase the size of the PM pool:\n");
  printf("Increase PSEGMENT_RESERVED_REGION_SIZE in benchmarks/echo/echo/include/pm_instr.h\n");
  //display();
  errno = ENOMEM;
  exit(EXIT_FAILURE);
  return NULL;
}
Пример #5
0
/* Encoder for vias.
 * Returns the length of the encoded structure in bytes
 * FORMAT (byte meanings):
 * 1: flags
 *
 */
int encode_via(char *hdrstart,int hdrlen,struct via_body *body,unsigned char *where)
{
   int i;/* 1*flags + 1*hostport_len*/
   unsigned char flags=0;

   where[1]=REL_PTR(hdrstart,body->name.s);
   where[2]=REL_PTR(hdrstart,body->version.s);
   where[3]=REL_PTR(hdrstart,body->transport.s);
   where[4]=REL_PTR(hdrstart,body->transport.s+body->transport.len+1);
   where[5]=REL_PTR(hdrstart,body->host.s);
   if(body->port_str.s && body->port_str.len){
      flags|=HAS_PORT_F;
      where[6]=REL_PTR(hdrstart,body->port_str.s);
      where[7]=REL_PTR(hdrstart,body->port_str.s+body->port_str.len+1);
      i=8;
   }else{
      where[6]=REL_PTR(hdrstart,body->host.s+body->host.len+1);
      i=7;
   }
   if(body->params.s && body->params.len){
      flags|=HAS_PARAMS_F;
      where[i++]=REL_PTR(hdrstart,body->params.s);
      where[i++]=(unsigned char)body->params.len;
   }
   if(body->branch && body->branch->value.s && body->branch->value.len){
      flags|=HAS_BRANCH_F;
      where[i++]=REL_PTR(hdrstart,body->branch->value.s);
      where[i++]=(unsigned char)body->branch->value.len;
   }
   if(body->received && body->received->value.s && body->received->value.len){
      flags|=HAS_RECEIVED_F;
      where[i++]=REL_PTR(hdrstart,body->received->value.s);
      where[i++]=(unsigned char)body->received->value.len;
   }
   if(body->rport && body->rport->value.s && body->rport->value.len){
      flags|=HAS_RPORT_F;
      where[i++]=REL_PTR(hdrstart,body->rport->value.s);
      where[i++]=(unsigned char)body->rport->value.len;
   }
   if(body->i && body->i->value.s && body->i->value.len){
      flags|=HAS_I_F;
      where[i++]=REL_PTR(hdrstart,body->i->value.s);
      where[i++]=(unsigned char)body->i->value.len;
   }
   if(body->alias && body->alias->value.s && body->alias->value.len){
      flags|=HAS_ALIAS_F;
      where[i++]=REL_PTR(hdrstart,body->alias->value.s);
      where[i++]=(unsigned char)body->alias->value.len;
   }

   where[0]=flags;
   i+=encode_parameters(&where[i],body->param_lst,hdrstart,(void *)body,'v');
   return i;
}