Esempio n. 1
0
/**
 * creates an as_event in shared memory and returns its address or NULL if error.
 * event_length(4) UNSIGNED INT includes the length 4 bytes itself
 * type(1),
 * processor_id(4),
 * flags(4),
 * transport(1).
 * src_ip_len(1),
 * src_ip(4 or 16),
 * dst_ip_len(1),
 * dst_ip(4 or 16),
 * src_port(2),
 * dst_port(2),
 *
 */
char * create_as_event_sl(struct sip_msg *msg,char processor_id,int *evt_len,int flags)
{
   unsigned int i;
   unsigned short int port;
   unsigned int k,len;
   char *buffer=NULL;

   if(!(buffer=shm_malloc(ENCODED_MSG_SIZE))){
      LM_ERR("create_as_event_t Out Of Memory !!\n");
      return 0;
   }
   *evt_len=0;

   /*leave 4 bytes for event length*/
   k=4;
   /*type*/
   buffer[k++]=(unsigned char)SL_REQ_IN;
   /*processor_id*/
   buffer[k++]=(unsigned char)processor_id;
   /*flags*/
   flags=htonl(flags);
   memcpy(buffer+k,&flags,4);
   k+=4;
   /*protocol should be UDP,TCP,TLS or whatever*/
   buffer[k++]=(unsigned char)msg->rcv.proto;
   /*src ip len + src ip*/
   len=msg->rcv.src_ip.len;
   buffer[k++]=(unsigned char)len;
   memcpy(buffer+k,&(msg->rcv.src_ip.u),len);
   k+=len;
   /*dst ip len + dst ip*/
   len=msg->rcv.dst_ip.len;
   buffer[k++]=(unsigned char)len;
   memcpy(buffer+k,&(msg->rcv.dst_ip.u),len);
   k+=len;
   /*src port */
   port=htons(msg->rcv.src_port);
   memcpy(buffer+k,&port,2);
   k+=2;
   /*dst port */
   port=htons(msg->rcv.dst_port);
   memcpy(buffer+k,&port,2);
   k+=2;
   /*length of event (hdr+payload-4), copied at the beginning*/
   if(encode_msg(msg,buffer+k,ENCODED_MSG_SIZE-k)<0){
      LM_ERR("Unable to encode msg\n");
      goto error;
   }
   i = GET_PAY_SIZE(buffer+k);
   k+=i;
   *evt_len=k;
   k=htonl(k);
   memcpy(buffer,&k,4);
   return buffer;
error:
   if(buffer)
      shm_free(buffer);
   return 0;
}
Esempio n. 2
0
int coded_buffered_printer(int infd)
{
   int i,lastlast;
   char spaces[50];
   static char mybuffer[1500];
   static int size=0,last=0;

   memcpy(spaces," ",2);

   do{
      lastlast=1500-last;
      i=read(infd,&mybuffer[last],lastlast);
      printf("read i=%d\n",i);
      if(i==0)
	 break;
      if(size==0){
	 size=GET_PAY_SIZE(mybuffer);
	 printf("size=%d\n",size);
	 last+=i;
      }
      if(last>=size){
	 printf("should print message: last=%d, size=%d\n",last,size);
	 if(print_encoded_msg(1,mybuffer,spaces)<0){
	    printf("Unable to print encoded msg\n");
	    return -1;
	 }
	 if(last>size){
	    memmove(mybuffer,&mybuffer[size],last-size);
	    last=last-size;
	 }else
	    last=0;
	 size=0;
      }
   }while(i>0 && i==lastlast);

   if(i==0)
      return 0;
   else
      return 1;
}
Esempio n. 3
0
/**
 * creates an as_event in shared memory and returns its address or NULL if error.
 * event_length(4) UNSIGNED INT includes the length 4 bytes itself
 * type(1),
 * flags(4),
 * transport(1).
 * src_ip_len(1),
 * src_ip(4 or 16),
 * dst_ip_len(1),
 * dst_ip(4 or 16),
 * src_port(2),
 * dst_port(2),
 * hash index(4),
 * label(4),
 * [cancelled hash_index,label]
 *
 */
char * create_as_event_t(struct cell *t,struct sip_msg *msg,char processor_id,int *evt_len,int flags)
{
   unsigned int i,hash_index,label;
   unsigned short int port;
   unsigned int k,len;
   char *buffer=NULL;
   struct cell *originalT;

   originalT=0;

   if(!(buffer=shm_malloc(ENCODED_MSG_SIZE))){
      LM_ERR("Out Of Memory !!\n");
      return 0;
   }
   *evt_len=0;
   if(t){
      hash_index=t->hash_index;
      label=t->label;
   }else{
      /**seas_f.tmb.t_get_trans_ident(msg,&hash_index,&label); this is bad, because it ref-counts !!!*/
      LM_ERR("no transaction provided...\n");
      goto error;
   }

   k=4;
   /*type*/
   buffer[k++]=(unsigned char)T_REQ_IN;
   /*processor_id*/
   buffer[k++]=(unsigned char)processor_id;
   /*flags*/
   if(is_e2e_ack(t,msg)){
      flags|=E2E_ACK;
   }else if(msg->REQ_METHOD==METHOD_CANCEL){
      LM_DBG("new CANCEL\n");
      originalT=seas_f.tmb.t_lookup_original_t(msg);
      if(!originalT || originalT==T_UNDEFINED){
	 /** we dont even pass the unknown CANCEL to JAIN*/
	 LM_WARN("CANCEL does not match any existing transaction!!\n");
	 goto error;
      }else{
	 flags|=CANCEL_FOUND;
	 //seas_f.tmb.unref_cell(originalT);
      }
      LM_DBG("Cancelling transaction !!\n");
   }
   flags=htonl(flags);
   memcpy(buffer+k,&flags,4);
   k+=4;
   /*protocol should be UDP,TCP,TLS or whatever*/
   buffer[k++]=(unsigned char)msg->rcv.proto;
   /*src ip len + src ip*/
   len=msg->rcv.src_ip.len;
   buffer[k++]=(unsigned char)len;
   memcpy(buffer+k,&(msg->rcv.src_ip.u),len);
   k+=len;
   /*dst ip len + dst ip*/
   len=msg->rcv.dst_ip.len;
   buffer[k++]=(unsigned char)len;
   memcpy(buffer+k,&(msg->rcv.dst_ip.u),len);
   k+=len;
   /*src port */
   port=htons(msg->rcv.src_port);
   memcpy(buffer+k,&port,2);
   k+=2;
   /*dst port */
   port=htons(msg->rcv.dst_port);
   memcpy(buffer+k,&port,2);
   k+=2;
   /*hash_index*/
   i=htonl(hash_index);
   memcpy(buffer+k,&i,4);
   k+=4;
   /*label (is the collision slot in the hash-table)*/
   i=htonl(label);
   memcpy(buffer+k,&i,4);
   k+=4;
   if(msg->REQ_METHOD==METHOD_CANCEL && originalT){
      LM_DBG("Cancelled transaction: Hash_Index=%d, Label=%d\n",originalT->hash_index,originalT->label);
      /*hash_index*/
      i=htonl(originalT->hash_index);
      memcpy(buffer+k,&i,4);
      k+=4;
      /*label (is the collision slot in the hash-table)*/
      i=htonl(originalT->label);
      memcpy(buffer+k,&i,4);
      k+=4;
   }

   /*length of event (hdr+payload-4), copied at the beginning*/
   if(encode_msg(msg,buffer+k,ENCODED_MSG_SIZE-k)<0){
      LM_ERR("Unable to encode msg\n");
      goto error;
   }
   i = GET_PAY_SIZE(buffer+k);
   k+=i;
   *evt_len=k;
   k=htonl(k);
   memcpy(buffer,&k,4);
   return buffer;
error:
   if(buffer)
      shm_free(buffer);
   return 0;
}
Esempio n. 4
0
/* This function extracts meta-info from the sip_msg structure and
 * formats it so that it can be used to rapidly access the message structured
 * parts.
 *
 * RETURNS: LENGTH of structure on success, <0 if failure
 * if there was failure, you dont need to pkg_free the payload (it is done inside).
 * if there was success, you __NEED_TO_PKG_FREE_THE_PAYLOAD__ from the calling function.
 *
 * The encoded meta-info is composed by 3 sections:
 *
 * MSG_META_INFO:
 * 2: short int in network-byte-order, if <100, the msg is a REQUEST and the int
 * is the code of the METHOD. if >100, it is a RESPONSE and the int is the code
 * of the response.
 * 2: short int in NBO: payload-start based pointer (index) to where the SIP MSG starts.
 * 2: short int in NBO: the sip-message length
 * 2: METHOD or CODE string SIP-START-based pointer and length
 * 2: R-URI or REASON PHRASE string SIP-START-based pointer and length
 * 2: VERSION string SIP-START-based pointer and length
 * 2: short int in NBO: start of the content of the SIP message
 * [1+N]: in case this is a request, the length of the encoded-uri and the encoded-uri
 * 1: how many present headers have been found.
 *
 * MSG_HEADERS_INDEX:
 * N*3: groups of 3 bytes, each one describing a header struct: the first byte
 * is a letter that corresponds to a header type, the second and third bytes are a NBO
 * inidex to where this struct begins within the HEADERS_META_INFO section.
 *
 * HEADERS_META_INFO:
 * M: all the codified headers meta info structs one after another
 *
 * SIP_MSG:
 * the SIP message as it has been received.
 *
 * The length of the structure, will be ((short*)payload)[1] + ((short*)payload)[2]
 *
 * TODO: msg->parsed_uri msg->parsed_orig_uri_ok, msg->first_line->u.request.uri
 * buggy and little bit fuzzy
 */
int encode_msg(struct sip_msg *msg,char *payload,int len)
{
    int i,j,k,u,request;
    unsigned short int h;
    struct hdr_field* hf;
    struct msg_start* ms;
    struct sip_uri miuri;
    char *myerror=NULL;
    ptrdiff_t diff;

    if(len < MAX_ENCODED_MSG + MAX_MESSAGE_LEN)
        return -1;
    if(parse_headers(msg,HDR_EOH_F,0)<0) {
        myerror="in parse_headers";
        goto error;
    }
    memset(payload,0,len);
    ms=&msg->first_line;
    if(ms->type == SIP_REQUEST)
        request=1;
    else if(ms->type == SIP_REPLY)
        request=0;
    else {
        myerror="message is neither request nor response";
        goto error;
    }
    if(request) {
        for(h=0; h<32; j=(0x01<<h),h++)
            if(j & ms->u.request.method_value)
                break;
    } else {
        h=(unsigned short)(ms->u.reply.statuscode);
    }
    if(h==32) { /*statuscode wont be 32...*/
        myerror="unknown message type\n";
        goto error;
    }
    h=htons(h);
    /*first goes the message code type*/
    memcpy(payload,&h,2);
    h=htons((unsigned short int)msg->len);
    /*then goes the message start idx, but we'll put it later*/
    /*then goes the message length (we hope it to be less than 65535 bytes...)*/
    memcpy(&payload[MSG_LEN_IDX],&h,2);
    /*then goes the content start index (starting from SIP MSG START)*/
    if(0>(diff=(get_body(msg)-(msg->buf)))) {
        myerror="body starts before the message (uh ?)";
        goto error;
    } else
        h=htons((unsigned short int)diff);
    memcpy(payload+CONTENT_IDX,&h,2);
    payload[METHOD_CODE_IDX]=(unsigned char)(request?
                             (ms->u.request.method.s-msg->buf):
                             (ms->u.reply.status.s-msg->buf));
    payload[METHOD_CODE_IDX+1]=(unsigned char)(request?
                               (ms->u.request.method.len):
                               (ms->u.reply.status.len));
    payload[URI_REASON_IDX]=(unsigned char)(request?
                                            (ms->u.request.uri.s-msg->buf):
                                            (ms->u.reply.reason.s-msg->buf));
    payload[URI_REASON_IDX+1]=(unsigned char)(request?
                              (ms->u.request.uri.len):
                              (ms->u.reply.reason.len));
    payload[VERSION_IDX]=(unsigned char)(request?
                                         (ms->u.request.version.s-msg->buf):
                                         (ms->u.reply.version.s-msg->buf));
    if(request) {
        if (parse_uri(ms->u.request.uri.s,ms->u.request.uri.len, &miuri)<0) {
            LM_ERR("<%.*s>\n",ms->u.request.uri.len,ms->u.request.uri.s);
            myerror="while parsing the R-URI";
            goto error;
        }
        if(0>(j=encode_uri2(msg->buf,
                            ms->u.request.method.s-msg->buf+ms->len,
                            ms->u.request.uri,&miuri,
                            (unsigned char*)&payload[REQUEST_URI_IDX+1])))
        {
            myerror="ENCODE_MSG: ERROR while encoding the R-URI";
            goto error;
        }
        payload[REQUEST_URI_IDX]=(unsigned char)j;
        k=REQUEST_URI_IDX+1+j;
    } else
        k=REQUEST_URI_IDX;
    u=k;
    k++;
    for(i=0,hf=msg->headers; hf; hf=hf->next,i++);
    i++;/*we do as if there was an extra header, that marks the end of
	 the previous header in the headers hashtable(read below)*/
    j=k+3*i;
    for(i=0,hf=msg->headers; hf; hf=hf->next,k+=3) {
        payload[k]=(unsigned char)(hf->type & 0xFF);
        h=htons(j);
        /*now goes a payload-based-ptr to where the header-code starts*/
        memcpy(&payload[k+1],&h,2);
        /*TODO fix this... fixed with k-=3?*/
        if(0>(i=encode_header(msg,hf,(unsigned char*)(payload+j),MAX_ENCODED_MSG+MAX_MESSAGE_LEN-j))) {
            LM_ERR("encoding header %.*s\n",hf->name.len,hf->name.s);
            goto error;
            k-=3;
            continue;
        }
        j+=(unsigned short int)i;
    }
    /*now goes the number of headers that have been found, right after the meta-msg-section*/
    payload[u]=(unsigned char)((k-u-1)/3);
    j=htons(j);
    /*now copy the number of bytes that the headers-meta-section has occupied,right afther
     * headers-meta-section(the array with ['v',[2:where],'r',[2:where],'R',[2:where],...]
     * this is to know where the LAST header ends, since the length of each header-struct
     * is calculated substracting the nextHeaderStart - presentHeaderStart
     * the k+1 is because payload[k] is usually the letter*/
    memcpy(&payload[k+1],&j,2);
    k+=3;
    j=ntohs(j);
    /*now we copy the headers-meta-section after the msg-headers-meta-section*/
    /*memcpy(&payload[k],payload2,j);*/
    /*j+=k;*/
    /*pkg_free(payload2);*/
    /*now we copy the actual message after the headers-meta-section*/
    memcpy(&payload[j],msg->buf,msg->len);
    LM_DBG("msglen = %d,msg starts at %d\n",msg->len,j);
    j=htons(j);
    /*now we copy at the beginning, the index to where the actual message starts*/
    memcpy(&payload[MSG_START_IDX],&j,2);
    return GET_PAY_SIZE( payload );
error:
    LM_ERR("%s\n",myerror);
    return -1;
}