Ejemplo n.º 1
0
// Get the SDP message from SIP message and check it's Content-Type
// Return values:
//    1 - success
//   -1 - error in getting body or invalid content type
//   -2 - empty message
static int
getSDPMessage(struct sip_msg *msg, str *sdp)
{
    sdp->s = get_body(msg);
    if (sdp->s==NULL) {
        LM_ERR("cannot get the SDP body\n");
        return -1;
    }

    sdp->len = msg->buf + msg->len - sdp->s;
    if (sdp->len == 0)
        return -2;

    if (!checkContentType(msg)) {
        LM_ERR("content type is not `application/sdp'\n");
        return -1;
    }

    return 1;
}
Ejemplo n.º 2
0
/*
 * in event specific publish handling - only check is good body format
 */
int	xml_publ_handl(struct sip_msg* msg, int* sent_reply)
{	
	str body= {0, 0};
	xmlDocPtr doc= NULL;

	*sent_reply= 0;
	if ( get_content_length(msg) == 0 )
		return 1;
	
	body.s=get_body(msg);
	if (body.s== NULL) 
	{
		LM_ERR("cannot extract body from msg\n");
		goto error;
	}
	/* content-length (if present) must be already parsed */

	body.len = get_content_length( msg );
	doc= xmlParseMemory( body.s, body.len );
	if(doc== NULL)
	{
		LM_ERR("bad body format\n");
		if( xml_sigb.reply( msg, 415, &pu_415_rpl, 0)== -1)
		{
			LM_ERR("while sending '415 Unsupported media type' reply\n");
		}
		*sent_reply = 1;
		goto error;
	}
	xmlFreeDoc(doc);
	xmlCleanupParser();
	xmlMemoryDump();
	return 1;

error:
	xmlFreeDoc(doc);
	xmlCleanupParser();
	xmlMemoryDump();
	return -1;

}
Ejemplo n.º 3
0
static int replace_body_f(struct sip_msg* msg, char* key, char* str2)
{
	struct lump* l;
	regmatch_t pmatch;
	char* s;
	int len;
	char* begin;
	int off;
	str body;

	if ( get_body(msg,&body)!=0 || body.len==0) {
		LM_DBG("message body has zero length\n");
		return -1;
	}

	begin=body.s; /* msg->orig previously .. uri problems */

	if (regexec((regex_t*) key, begin, 1, &pmatch, 0)!=0) return -1;
	off=begin-msg->buf;

	if (pmatch.rm_so!=-1){
		if ((l=del_lump(msg, pmatch.rm_so+off,
						pmatch.rm_eo-pmatch.rm_so, 0))==0)
			return -1;
		len=strlen(str2);
		s=pkg_malloc(len);
		if (s==0){
			LM_ERR("memory allocation failure\n");
			return -1;
		}
		memcpy(s, str2, len);
		if (insert_new_lump_after(l, s, len, 0)==0){
			LM_ERR("could not insert new lump\n");
			pkg_free(s);
			return -1;
		}

		return 1;
	}
	return -1;
}
Ejemplo n.º 4
0
// Formulate and send world description to viewers
void World::send_to_viewers(const boost::system::error_code& ec)
{
  if (!ec)
  {
    std::string message;
    
    if (bodies_.size() > 0)
    {
      // Formulate message from bodies
      for (int i=0; i<num_bodies(); i++)
        message += get_body(i)->get_viewer_msg();
    
      // Send to all viewers
      for (uint i=0; i<viewers_.size(); i++)
        viewers_[i]->send_message(message);
    }

    // Call self later
    viewer_timer_.expires_at(viewer_timer_.expires_at() + boost::posix_time::seconds(viewer_ts_));
    viewer_timer_.async_wait(boost::bind(&World::send_to_viewers, this, boost::asio::placeholders::error));
  }
}
Ejemplo n.º 5
0
/*
 * Get message body and check Content-Type header field
 */
int extract_body(struct sip_msg *msg, str *body )
{
	char c;
	int skip;

	if ( get_body(msg,body)!=0 || body->len==0) {
		LM_ERR("failed to get the message body\n");
		goto error;
	}

	/* no need for parse_headers(msg, EOH), get_body will
	 * parse everything */
	/*is the content type correct?*/
	if (check_content_type(msg)==-1)
	{
		LM_ERR("content type mismatching\n");
		goto error;
	}

	for (skip = 0; skip < body->len; skip++) {
		c = body->s[body->len - skip - 1];
		if (c != '\r' && c != '\n')
			break;
	}
	if (skip == body->len) {
		LM_ERR("empty body\n");
		goto error;
	}
	body->len -= skip;

	/*LM_DBG("DEBUG:extract_body:%d=|%.*s|\n",body->len,body->len,body->s);*/

	return 1;
error:
	body->s = NULL;
	body->len = 0;
	return -1;
}
Ejemplo n.º 6
0
int complete_mes(char *mes, int size) {
	int cl = 0, headers = 0, len = 0;
	char *tmp = NULL;

	cl = get_cl(mes);
#ifdef DEBUG
	printf("CL: %i\n", cl);
#endif
	if (cl < 0){
		printf("missing CL header; waiting for more bytes...\n");
		return 0;
	}
	tmp = get_body(mes);
#ifdef DEBUG
	printf("body: '%s'\n", tmp);
#endif
	headers = tmp - mes;
#ifdef DEBUG
	printf("length: %i, headers: %i\n", size, headers);
#endif
	len = headers + cl;
	if (len == size) {
		printf("message is complete\n");
		return 1;
	}
	else if (len > size) {
		printf("waiting for more bytes...\n");
		return 0;
	}
	else {
		/* we received more then the sender claims to sent
		 * for now we treat this as a complete message
		 * FIXME: should we store the extra bytes in a buffer and
		 *        truncate the message at the calculated length !? */
		printf("received too much bytes...\n");
		return 1;
	}
}
Ejemplo n.º 7
0
void
Ex5::do_opt_unit(OptUnit *unit)
{
    IdString name = get_name(get_proc_sym(unit));
    printf("Processing procedure \"%s\"\n", name.chars());

    // get the body of the OptUnit
    AnyBody *body = get_body(unit);

    // verify that it is an InstrList
    claim (is_a<InstrList>(body),
           "expected OptUnit's body in InstrList form");
    InstrList *mil = (InstrList *)body;

    for (InstrHandle h = start(mil); h != end(mil); ) {
	InstrHandle cur_h = h++;	// advance before possible instr removal
        Instr *mi = *cur_h;

	if (has_note(mi, k_reserved_reg_load) ||
	    has_note(mi, k_store_reserved_reg))
	    delete remove(mil, cur_h);
    }
}
Ejemplo n.º 8
0
static int search_append_body_f(struct sip_msg* msg, char* key, char* str2)
{
	struct lump* l;
	regmatch_t pmatch;
	char* s;
	int len;
	int off;
	str body;

	if ( get_body(msg,&body)!=0 || body.len==0) {
		LM_DBG("message body has zero length\n");
		return -1;
	}

	off=body.s-msg->buf;

	if (regexec((regex_t*) key, body.s, 1, &pmatch, 0)!=0) return -1;
	if (pmatch.rm_so!=-1){
		if ((l=anchor_lump(msg, off+pmatch.rm_eo, 0))==0)
			return -1;
		len=strlen(str2);
		s=pkg_malloc(len);
		if (s==0){
			LM_ERR("memory allocation failure\n");
			return -1;
		}
		memcpy(s, str2, len);
		if (insert_new_lump_after(l, s, len, 0)==0){
			LM_ERR("could not insert new lump\n");
			pkg_free(s);
			return -1;
		}
		return 1;
	}
	return -1;
}
Ejemplo n.º 9
0
static int w_remove_body_f(struct sip_msg *msg, char *p1, char *p2)
{
	str body = {0,0};

	body.len = 0;
	body.s = get_body(msg);
	if (body.s==0)
	{
		LM_DBG("no body in the message\n");
		return 1;
	}
	body.len = msg->buf + msg->len - body.s;
	if (body.len<=0)
	{
		LM_DBG("empty body in the message\n");
		return 1;
	}
	if(del_lump(msg, body.s - msg->buf, body.len, 0) == 0)
	{
		LM_ERR("cannot remove body\n");
		return -1;
	}
	return 1;
}
Ejemplo n.º 10
0
int reginfo_handle_notify(struct sip_msg* msg, char* domain, char* s2) {

    LM_DBG("Handling notify\n");
    str body;
    int result = 1;
    
    if(subscribe_to_reginfo != 1){
        LM_ERR("Received a NOTIFY for reg-info but I have not SUBSCRIBED for them.  Ignoring");
        return -1;
    }

    /* If not done yet, parse the whole message now: */
    if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
        LM_ERR("Error parsing headers\n");
        return -1;
    }
    if (get_content_length(msg) == 0) {
        LM_DBG("Content length = 0\n");
        /* No Body? Then there is no published information available, which is ok. */
        return 1;
    } else {
        body.s = get_body(msg);
        if (body.s == NULL) {
            LM_ERR("cannot extract body from msg\n");
            return -1;
        }
        body.len = get_content_length(msg);
    }

    LM_DBG("Body is %.*s\n", body.len, body.s);

    result = process_body(msg, body, (udomain_t*) domain);


    return result;
}
Ejemplo n.º 11
0
/*
 * Update existing presentity and watcher list
 */
static int publish_presentity_pidf(struct sip_msg* _m, struct pdomain* _d, struct presentity* presentity, int *pchanged)
{
     char *body = get_body(_m);
     presence_tuple_t *tuple = NULL;
     str contact = { NULL, 0 };
     str basic = { NULL, 0 };
     str status = { NULL, 0 };
     str location = { NULL, 0 };
     str site = { NULL, 0 };
     str floor = { NULL, 0 };
     str room = { NULL, 0 };
     str packet_loss = { NULL, 0 };
     double x=0, y=0, radius=0;
     time_t expires = act_time + default_expires;
     double priority = default_priority;
     int prescaps = 0;
     int flags = 0;
     int changed = 0;
     int ret = 0;

     flags = parse_pidf(body, &contact, &basic, &status, &location, &site, &floor, &room, &x, &y, &radius, 
			&packet_loss, &priority, &expires, &prescaps);
     if (contact.len) {
	  find_presence_tuple(&contact, presentity, &tuple);
	  if (!tuple && new_tuple_on_publish) {
	       new_presence_tuple(&contact, expires, presentity, &tuple);
	       add_presence_tuple(presentity, tuple);
	       changed = 1;
	  }
     } else {
	  tuple = presentity->tuples;
     }
     if (!tuple) {
	  LOG(L_ERR, "publish_presentity: no tuple for %.*s\n", 
	      presentity->uri.len, presentity->uri.s);
	  return -1;
     }

     LOG(L_INFO, "publish_presentity_pidf: -1-\n");
     if (basic.len && basic.s) {
	  int origstate = tuple->state;
	  tuple->state =
	       ((strcasecmp(basic.s, "online") == 0) || (strcasecmp(basic.s, "open") == 0)) ? PS_ONLINE : PS_OFFLINE;
	  if (tuple->state != origstate)
	       changed = 1;
     }
     if (status.len && status.s) {
	  if (tuple->status.len && str_strcasecmp(&tuple->status, &status) != 0)
	       changed = 1;
	  tuple->status.len = status.len;
	  strncpy(tuple->status.s, status.s, status.len);
	  tuple->status.s[status.len] = 0;
     }
     LOG(L_INFO, "publish_presentity: -2-\n");
     if (location.len && location.s) {
	  if (tuple->location.loc.len && str_strcasecmp(&tuple->location.loc, &location) != 0)
	       changed = 1;
	  tuple->location.loc.len = location.len;
	  strncpy(tuple->location.loc.s, location.s, location.len);
	  tuple->location.loc.s[location.len] = 0;
     } else if (flags & PARSE_PIDF_LOCATION_MASK) {
	  tuple->location.loc.len = 0;
     }
     if (site.len && site.s) {
	  if (tuple->location.site.len && str_strcasecmp(&tuple->location.site, &site) != 0)
	       changed = 1;
	  tuple->location.site.len = site.len;
	  strncpy(tuple->location.site.s, site.s, site.len);
	  tuple->location.site.s[site.len] = 0;
     } else if (flags & PARSE_PIDF_LOCATION_MASK) {
	  tuple->location.site.len = 0;
     }
     if (floor.len && floor.s) {
	  if (tuple->location.floor.len && str_strcasecmp(&tuple->location.floor, &floor) != 0)
	       changed = 1;
	  tuple->location.floor.len = floor.len;
	  strncpy(tuple->location.floor.s, floor.s, floor.len);
	  tuple->location.floor.s[floor.len] = 0;
     }else if (flags & PARSE_PIDF_LOCATION_MASK) {
	  tuple->location.floor.len = 0;
     }
     if (room.len && room.s) {
	  if (tuple->location.room.len && str_strcasecmp(&tuple->location.room, &room) != 0)
	       changed = 1;
	  tuple->location.room.len = room.len;
	  strncpy(tuple->location.room.s, room.s, room.len);
	  tuple->location.room.s[room.len] = 0;
     } else if (flags & PARSE_PIDF_LOCATION_MASK) {
	  tuple->location.room.len = 0;
     }
     if (packet_loss.len && packet_loss.s) {
	  if (tuple->location.packet_loss.len && str_strcasecmp(&tuple->location.packet_loss, &packet_loss) != 0)
	       changed = 1;
	  tuple->location.packet_loss.len = packet_loss.len;
	  strncpy(tuple->location.packet_loss.s, packet_loss.s, packet_loss.len);
	  tuple->location.packet_loss.s[packet_loss.len] = 0;
     } else if (flags & PARSE_PIDF_LOCATION_MASK) {
	  tuple->location.packet_loss.len = 0;
     }
     if (x) {
	  if (tuple->location.x != x)
	       changed = 1;
	  tuple->location.x = x;
     } else if (flags & PARSE_PIDF_LOCATION_MASK) {
	  tuple->location.x = 0;
     }
     if (y) {
	  if (tuple->location.y != y)
	       changed = 1;
	  tuple->location.y = y;
     } else if (flags & PARSE_PIDF_LOCATION_MASK) {
	  tuple->location.y = 0;
     }
     if (radius) {
	  if (tuple->location.radius != radius)
	       changed = 1;
	  tuple->location.radius = radius;
     } else if (flags & PARSE_PIDF_LOCATION_MASK) {
	  tuple->location.radius = 0;
     }

     if (tuple->priority != priority) {
       changed = 1;
       tuple->priority = priority;
     }
     if (tuple->expires != expires) {
       changed = 1;
       tuple->expires = expires;
     }
     if (use_location_package)
	  if (site.len && floor.len && room.len && changed) {
	       location_package_location_add_user(_d, &site, &floor, &room, presentity);
	  }
     if (flags & PARSE_PIDF_PRESCAPS) {
       if (tuple->prescaps != prescaps)
	 changed = 1;
       tuple->prescaps = prescaps;
     }

     changed = 1;
     if (changed)
	  presentity->flags |= PFLAG_PRESENCE_CHANGED;

     LOG(L_INFO, "publish_presentity: -3-: changed=%d\n", changed);
     if (pchanged && changed) {
	  *pchanged = 1;
     }

     if ((ret = db_update_presentity(presentity)) < 0) {
	  return ret;
     }

     LOG(L_INFO, "publish_presentity: -4-\n");
     return 0;
}
Ejemplo n.º 12
0
/**
 * sngtc_caller_answer - attaches an SDP body to ACK requests
 */
static int sngtc_caller_answer(struct sip_msg *msg)
{
	char *p;
	str body;
	struct dlg_cell *dlg;
	struct lump *lump;
	struct sngtc_info *info;
	int len;

	LM_DBG("processing ACK\n");

	if (get_body(msg, &body) != 0 || body.len > 0) {
		LM_ERR("ACK should not contain a SDP body\n");
		return SNGTC_ERR;
	}

	dlg = dlg_binds.get_dlg();
	if (!dlg) {
		LM_ERR("failed to fetch current dialog\n");
		return SNGTC_ERR;
	}

	/* get the SDP body from the INVITE which was mangled at 200 OK */
	if (dlg_binds.fetch_dlg_value(dlg, &dlg_key_sngtc_info, &body, 0) != 0) {
		LM_ERR("failed to fetch caller sdp\n");
		return SNGTC_ERR;
	}

	info = *(struct sngtc_info **)(body.s);

	/* duplicate the SDP in pkg mem for the lumps mechanism */
	if (pkg_str_dup(&body, &info->modified_caller_sdp) != 0) {
		LM_ERR("failed to dup in pkg mem\n");
		return SNGTC_ERR;
	}

	LM_DBG("Duplicated SDP: '%.*s'\n", body.len, body.s);

	lump = anchor_lump(msg, msg->content_length->name.s - msg->buf, 0);
	if (!lump) {
		LM_ERR("failed to insert anchor lump\n");
		return SNGTC_ERR;
	}

	p = pkg_malloc(SDP_CONTENT_TYPE_LEN);
	if (!p) {
		LM_ERR("no more pkg memory\n");
		return SNGTC_ERR;
	}

	/* add the Content-Type header */

	memcpy(p, "Content-Type: application/sdp\r\n", SDP_CONTENT_TYPE_LEN);

	if (!insert_new_lump_before(lump, p, SDP_CONTENT_TYPE_LEN, 0)) {
		LM_ERR("failed to insert Content-Type lump\n");
		return SNGTC_ERR;
	}

	LM_DBG("blen: %d\n", msg->content_length->body.len);

	lump = del_lump(msg, msg->content_length->body.s - msg->buf,
	                msg->content_length->body.len, HDR_OTHER_T);
	if (!lump) {
		LM_ERR("failed to insert del lump for the content length\n");
		return SNGTC_ERR;
	}

	p = pkg_malloc(CONTENT_LEN_DIGITS);
	if (!p) {
		LM_ERR("no more pkg memory\n");
		return SNGTC_ERR;
	}

	LM_DBG("len: %d\n", body.len);

	len = sprintf(p, "%d", body.len);

	if (!insert_new_lump_after(lump, p, len, HDR_OTHER_T)) {
		LM_ERR("failed to insert Content-Length lump\n");
		return SNGTC_ERR;
	}

	lump = anchor_lump(msg, msg->len - CRLF_LEN, 0);
	if (!lump) {
		LM_ERR("failed to insert anchor lump\n");
		return SNGTC_ERR;
	}

	if (!insert_new_lump_before(lump, body.s, body.len, 0)) {
		LM_ERR("failed to insert SDP body lump\n");
		return SNGTC_ERR;
	}

	return 1;
}
Ejemplo n.º 13
0
void
cddbd_mail(int flags)
{
	int ret;
	FILE *fp;
	FILE *tfp= (FILE *) 0;
	FILE *tfp2= (FILE *) 0;
	email_hdr_t eh;
	char *tmail;
	char *tmail2;
	char *tmail3;
	char buf[CDDBBUFSIZ];
	char errstr[CDDBBUFSIZ];

	errstr[0] = '\0';

	/* Create a temporary file for the mail. */
	tmail = cddbd_mktemp();

	if((fp = fopen(tmail, "w+")) == NULL) {
		cddbd_snprintf(buf, sizeof(buf),
		    "Can't open mail tmp file %s (%d)", tmail, errno);

		cddbd_log(LOG_ERR | LOG_MAIL, "%s", buf);

		/* Print to stderr so the bounced mail gets it. */
		fprintf(stderr, "%s\n", buf);

		quit(QUIT_ERR);
	}

	/* Put the mail into the temp file. */
	while(fgets(buf, sizeof(buf), stdin) != NULL) {
		if(fputs(buf, fp) == EOF) {
			cddbd_snprintf(buf, sizeof(buf),
			    "Can't write mail tmp file %s (%d)", tmail, errno);

			cddbd_log(LOG_ERR | LOG_MAIL, "%s", buf);

			/* Print to stderr so the bounced mail gets it. */
			fprintf(stderr, "%s\n", buf);

			quit(QUIT_ERR);
		}
	}

	/* Put the pointer back to the start of the file for reading. */
	rewind(fp);

	/* parse the header, fill in "eh" structure */
	ret = parse_header(fp, &eh, errstr);

	tmail2 = cddbd_mktemp();

	if(ret == EE_OK && (tfp = get_body(fp, &eh, tmail2, errstr)) == NULL)
		ret = EE_ERROR;
	
	/* Put the pointer back to the start of the file for reading. */
	rewind(fp);
	
	tmail3 = cddbd_mktemp();
	
	if(ret == EE_OK && (tfp2=build_returnmail(fp, tfp, tmail3, errstr)) == NULL)
		ret = EE_ERROR;
		
	if(ret == EE_OK) {
		switch(eh.eh_class) {
		case EC_SUBMIT:
			ret = cddbd_submit(tfp, &eh, flags, errstr);

			/* Give back happy mail. */
			if(ret == EE_OK && (flags & MF_TEST)) {
				ret = return_mail(tfp2, &eh, flags, errstr);

				if(ret != EE_OK) {
					cddbd_log(LOG_ERR | LOG_MAIL,
						"Couldn't send test response.");
				}
			}

			break;

		case EC_COMMAND:
			ret = cddbd_email_cmd(tfp, &eh, flags, errstr);
			break;

		case EC_NONE:
		default:
			ret = EE_ERROR;
			break;
		}
	}

	if(ret != EE_OK) {
		if(eh.eh_flags & EH_RCPT) {
			/* We have a sender, give him mail directly. */
			if (tfp2 != NULL)
				ret = return_mail(tfp2, &eh, (flags | MF_FAIL), errstr);
			else
				ret = return_mail(fp, &eh, (flags | MF_FAIL), errstr);
		}

		if(ret != EE_OK) {
			/* We have no sender, give him mail indirectly. */
			cddbd_snprintf(buf, sizeof(buf),
			    "Unable to process email: %s", errstr);

			cddbd_log(LOG_ERR | LOG_MAIL, "%s", buf);

			/* Print to stderr so the bounced mail gets it. */
			fprintf(stderr, "%s\n", buf);
		}
	}

	fclose(fp);
	if (tfp != (FILE *) 0) fclose(tfp);
	if (tfp2 != (FILE *) 0) fclose(tfp2);

	cddbd_freetemp(tmail);
	cddbd_freetemp(tmail2);
	cddbd_freetemp(tmail3);

	if(ret == EE_OK)
		quit(QUIT_OK);
	else
		quit(QUIT_ERR);
}
Ejemplo n.º 14
0
/*
 * Function to decompress a compressed message
 */
static int mc_decompress(struct sip_msg* msg)
{
	#define HDRS_TO_SKIP 4

	int i;
	int j;
	int rc;
	int algo=-1;
	int hdrs_algo=-1;
	int b64_required=-1;

	str msg_body;
	str msg_final;

	str b64_decode={NULL, 0};
	str hdr_b64_decode={NULL,0};
	str uncomp_body={NULL,0};
	str uncomp_hdrs={NULL,0};

	char *new_buf;

	unsigned long temp;

	/* hdr_vec allows to sort the headers. This will help skipping
		these headers when building the new message */
	struct hdr_field *hf;
	struct hdr_field *hdr_vec[HDRS_TO_SKIP];
					/*hdr_vec : 	0 Content-Length
							1 Comp-Hdrs
							2 Headers-Algo
							3 Content-Encoding*/

	memset(hdr_vec, 0, HDRS_TO_SKIP * sizeof(struct hdr_field*));

	if (parse_headers(msg, HDR_EOH_F, 0) != 0) {
		LM_ERR("failed to parse SIP message\n");
		return -1;
	}

	/*If compressed with this module there are great chances that Content-Encoding is last*/
	hdr_vec[3] = msg->last_header;

	if (!is_content_encoding(hdr_vec[3])) {
		hdr_vec[3] = NULL;
		for (hf = msg->headers; hf; hf = hf->next) {
			if (is_content_encoding(hf)) {
				hdr_vec[3] = hf;
				continue;
			}
			if (hf->type == HDR_OTHER_T &&
				!strncasecmp(hf->name.s, COMP_HDRS,COMP_HDRS_LEN)) {
				hdr_vec[1] = hf;
				continue;
			}

			if (hf->type == HDR_OTHER_T &&
				!strncasecmp(hf->name.s, HDRS_ENCODING,
						sizeof(HDRS_ENCODING)-1)) {
				hdr_vec[2] = hf;
			}

			if (hdr_vec[1] && hdr_vec[2] && hdr_vec[3])
					break;
		}
	} else {
		for (hf = msg->headers; hf; hf = hf->next) {
			if (!hdr_vec[1] && hf->type == HDR_OTHER_T &&
				!strncasecmp(hf->name.s, COMP_HDRS,COMP_HDRS_LEN)) {
				hdr_vec[1] = hf;
				continue;
			}

			if (!hdr_vec[2] && hf->type == HDR_OTHER_T &&
				!strncasecmp(hf->name.s, HDRS_ENCODING,
						sizeof(HDRS_ENCODING)-1))
				hdr_vec[2] = hf;

			if (hdr_vec[2] && hdr_vec[3] && hdr_vec[1])
					break;
		}
	}

	/* Only if content-encoding present, Content-Length will be replaced
		with the one in the compressed body or in compressed headers*/

	if (hdr_vec[3]) {
		hdr_vec[0] = msg->content_length;
		parse_algo_hdr(hdr_vec[3], &algo, &b64_required);
	}


	if (b64_required > 0 && hdr_vec[3]) {
		msg_body.s = msg->last_header->name.s + msg->last_header->len + CRLF_LEN;
		msg_body.len = strlen(msg_body.s);

		/* Cutting CRLF'S at the end of the message */
		while (WORD(msg_body.s + msg_body.len-CRLF_LEN) == PARSE_CRLF) {
			msg_body.len -= CRLF_LEN;
		}

		if (wrap_realloc(&body_in, calc_max_base64_decode_len(msg_body.len)))
			return -1;

		b64_decode.s = body_in.s;

		b64_decode.len = base64decode((unsigned char*)b64_decode.s,
						(unsigned char*)msg_body.s,
							msg_body.len);
	} else if (hdr_vec[3]) {
		if (get_body(msg, &msg_body) < 0) {
			LM_ERR("failed to get body\n");
			return -1;
		}

		b64_decode.s = msg_body.s;
		b64_decode.len = msg_body.len;
	}

	b64_required=0;
	if (hdr_vec[2]) {
		parse_algo_hdr(hdr_vec[3], &algo, &b64_required);
	}

	if (b64_required > 0 &&  hdr_vec[1]) {
		if (wrap_realloc(&hdr_in, calc_max_base64_decode_len(hdr_vec[1]->body.len)))
			return -1;

		hdr_b64_decode.s = hdr_in.s;

		hdr_b64_decode.len = base64decode(
					(unsigned char*)hdr_b64_decode.s,
					(unsigned char*)hdr_vec[1]->body.s,
							hdr_vec[1]->body.len
					);
	} else if (hdr_vec[1]) {
		hdr_b64_decode.s = hdr_vec[1]->body.s;
		hdr_b64_decode.len = hdr_vec[1]->body.len;
	}

	switch (hdrs_algo) {
		case 0: /* deflate */
			temp = (unsigned long)BUFLEN;

			rc = uncompress((unsigned char*)hdr_buf,
					&temp,
					(unsigned char*)hdr_b64_decode.s,
					(unsigned long)hdr_b64_decode.len);

			uncomp_hdrs.s = hdr_buf;
			uncomp_hdrs.len = temp;

			if (check_zlib_rc(rc)) {
				LM_ERR("header decompression failed\n");
				return -1;
			}
			break;
		case 1: /* gzip */
			rc = gzip_uncompress(
					(unsigned char*)hdr_b64_decode.s,
					(unsigned long)hdr_b64_decode.len,
					&hdr_out,
					&temp);

			if (check_zlib_rc(rc)) {
				LM_ERR("header decompression failed\n");
				return -1;
			}

			uncomp_hdrs.s = hdr_out.s;
			uncomp_hdrs.len = temp;

			break;
		case -1:
			break;
		default:
			return -1;
	}

	switch (algo) {
		case 0: /* deflate */
			temp = (unsigned long)BUFLEN;

			rc = uncompress((unsigned char*)body_buf,
					&temp,
					(unsigned char*)b64_decode.s,
					(unsigned long)b64_decode.len);

			if (check_zlib_rc(rc)) {
				LM_ERR("body decompression failed\n");
				return -1;
			}

			uncomp_body.s = body_buf;
			uncomp_body.len = temp;

			break;
		case 1: /* gzip */
			rc = gzip_uncompress(
					(unsigned char*)b64_decode.s,
					(unsigned long)b64_decode.len,
					&body_out,
					&temp);

			if (check_zlib_rc(rc)) {
				LM_ERR("body decompression failed\n");
				return -1;
			}

			uncomp_body.s = body_out.s;
			uncomp_body.len = temp;

			break;
		case -1:
			LM_DBG("no body\n");
			break;
		default:
			LM_ERR("invalid algo\n");
			return -1;
	}

	/* Sort to have the headers in order */
	for (i = 0; i < HDRS_TO_SKIP - 1; i++) {
		for (j = i + 1; j < HDRS_TO_SKIP; j++) {
			if (!hdr_vec[j])
				continue;

			if (!hdr_vec[i] && hdr_vec[j]) {
				hdr_vec[i] = hdr_vec[j];
				hdr_vec[j] = NULL;
			}

			if ((hdr_vec[i] && hdr_vec[j]) &&
				(hdr_vec[i]->name.s > hdr_vec[j]->name.s)) {
				hf = hdr_vec[i];
				hdr_vec[i] = hdr_vec[j];
				hdr_vec[j] = hf;
			}
		}
	}

	int msg_final_len = 0;
	int msg_ptr=0;

	for ( i = 0; i < HDRS_TO_SKIP; i++) {
		if (hdr_vec[i]) {
			msg_final_len += hdr_vec[i]->name.s - (msg->buf+msg_ptr);
			msg_ptr += hdr_vec[i]->name.s+hdr_vec[i]->len - (msg->buf+msg_ptr);
		}
	}

	msg_final_len += msg->last_header->name.s + msg->last_header->len -
				(msg->buf + msg_ptr);

	if (hdrs_algo >= 0)
		msg_final_len += uncomp_hdrs.len;

	if (algo >= 0)
		msg_final_len += uncomp_body.len;
	else
		msg_final_len += strlen(msg->eoh);

	if (wrap_realloc(&buf_out, msg_final_len))
		return -1;

	msg_ptr = 0;

	msg_final.len = 0;
	msg_final.s = buf_out.s;

	for ( i = 0; i < HDRS_TO_SKIP; i++) {
		if (hdr_vec[i]) {
			wrap_copy_and_update(&msg_final.s,
					msg->buf+msg_ptr,
					hdr_vec[i]->name.s-(msg->buf+msg_ptr),
					&msg_final.len);

			msg_ptr += (hdr_vec[i]->name.s+hdr_vec[i]->len) -
					(msg->buf+msg_ptr);
		}
	}

	wrap_copy_and_update(
			&msg_final.s,
			msg->buf+msg_ptr,
			(msg->last_header->name.s+msg->last_header->len)-
							(msg->buf+msg_ptr),
			&msg_final.len
		);

	if (hdrs_algo >= 0) {
		wrap_copy_and_update(&msg_final.s, uncomp_hdrs.s,
					uncomp_hdrs.len,&msg_final.len);
	}

	if (algo >= 0) {
		wrap_copy_and_update(&msg_final.s, uncomp_body.s,
					uncomp_body.len, &msg_final.len);
	} else {
		wrap_copy_and_update(&msg_final.s, msg->eoh, strlen(msg->eoh), &msg_final.len);
	}

	/* new buffer because msg_final(out_buf) will
	 * be overwritten at next iteration */
#ifdef DYN_BUF
	new_buf = pkg_malloc(msg_final.len+1);
	if (new_buf == NULL) {
		LM_ERR("no more pkg mem\n");
		return -1;
	}
#else
	new_buf = msg->buf;
#endif

	memcpy(new_buf, msg_final.s, msg_final.len);
	new_buf[msg_final.len] = '\0';

	struct sip_msg tmp;

	memcpy(&tmp, msg, sizeof(struct sip_msg));

	/*reset dst_uri and path_vec to avoid free*/
	if (msg->dst_uri.s != NULL) {
		msg->dst_uri.s = NULL;
		msg->dst_uri.len = 0;
	}
	if (msg->path_vec.s != NULL)
	{
		msg->path_vec.s = NULL;
		msg->path_vec.len = 0;
	}

	free_sip_msg(msg);
	memset(msg, 0, sizeof(struct sip_msg));

	/* restore msg fields */
	msg->id					= tmp.id;
	msg->rcv				= tmp.rcv;
	msg->set_global_address = tmp.set_global_address;
	msg->set_global_port    = tmp.set_global_port;
	msg->flags              = tmp.flags;
	msg->msg_flags          = tmp.msg_flags;
	msg->hash_index         = tmp.hash_index;
	msg->force_send_socket  = tmp.force_send_socket;
	msg->dst_uri            = tmp.dst_uri;
	msg->path_vec           = tmp.path_vec;
	/* set the new ones */
	msg->buf = new_buf;
	msg->len = msg_final.len;

	/* reparse the message */
	if (parse_msg(msg->buf, msg->len, msg) != 0)
		LM_ERR("parse_msg failed\n");

	return 1;
}
Ejemplo n.º 15
0
int rls_handle_notify(struct sip_msg* msg, char* c1, char* c2)
{
	struct to_body *pto, TO = {0}, *pfrom = NULL;
	str body= {0, 0};
	ua_pres_t dialog;
	str* res_id= NULL;
	db_key_t query_cols[8];
	db_val_t query_vals[8];
	int n_query_cols= 0;
	str auth_state= {0, 0};
	int found= 0;
	str reason = {0, 0};
	int auth_flag;
	struct hdr_field* hdr= NULL;
	int expires= -1;
	str content_type= {0, 0};
	int reply_code = 500;
	str reply_str = pu_500_rpl;

	LM_DBG("start\n");
	/* extract the dialog information and check if an existing dialog*/	
	if( parse_headers(msg,HDR_EOH_F, 0)==-1 )
	{
		LM_ERR("parsing headers\n");
		reply_code = 400;
		reply_str = pu_400_rpl;
		goto error;
	}
	if((!msg->event ) ||(msg->event->body.len<=0))
	{
		LM_ERR("Missing event header field value\n");
		reply_code = 400;
		reply_str = pu_400_rpl;
		goto error;
	}
	if( msg->to==NULL || msg->to->body.s==NULL)
	{
		LM_ERR("cannot parse TO header\n");
		reply_code = 400;
		reply_str = pu_400_rpl;
		goto error;
	}
	if(msg->to->parsed != NULL)
	{
		pto = (struct to_body*)msg->to->parsed;
		LM_DBG("'To' header ALREADY PARSED: <%.*s>\n",
				pto->uri.len, pto->uri.s );	
	}
	else
	{
		parse_to(msg->to->body.s,msg->to->body.s + msg->to->body.len + 1, &TO);
		if(TO.uri.len <= 0) 
		{
			LM_ERR(" 'To' header NOT parsed\n");
			reply_code = 400;
			reply_str = pu_400_rpl;
			goto error;
		}
		pto = &TO;
	}
	memset(&dialog, 0, sizeof(ua_pres_t));
	dialog.watcher_uri= &pto->uri;
	if (pto->tag_value.s==NULL || pto->tag_value.len==0 )
	{
		LM_ERR("to tag value not parsed\n");
		reply_code = 400;
		reply_str = pu_400_rpl;
		goto error;
	}
	dialog.from_tag= pto->tag_value;
	if( msg->callid==NULL || msg->callid->body.s==NULL)
	{
		LM_ERR("cannot parse callid header\n");
		reply_code = 400;
		reply_str = pu_400_rpl;
		goto error;
	}
	dialog.call_id = msg->callid->body;

	if (!msg->from || !msg->from->body.s)
	{
		LM_ERR("cannot find 'from' header!\n");
		reply_code = 400;
		reply_str = pu_400_rpl;
		goto error;
	}
	if (msg->from->parsed == NULL)
	{
		LM_DBG("'From' header not parsed\n");
		/* parsing from header */
		if ( parse_from_header( msg )<0 ) 
		{
			LM_ERR("cannot parse From header\n");
			reply_code = 400;
			reply_str = pu_400_rpl;
			goto error;
		}
	}
	pfrom = (struct to_body*)msg->from->parsed;
	dialog.pres_uri= &pfrom->uri;

	if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0)
	{
		LM_ERR("no from tag value present\n");
		reply_code = 400;
		reply_str = pu_400_rpl;
		goto error;
	}
	dialog.to_tag= pfrom->tag_value;
	dialog.flag|= RLS_SUBSCRIBE;

	dialog.event= get_event_flag(&msg->event->body);
	if(dialog.event< 0)
	{
		LM_ERR("unrecognized event package\n");
		reply_code = 489;
		reply_str = pu_489_rpl;
		goto error;
	}

	/* extract the subscription state */
	hdr = msg->headers;
	while (hdr!= NULL)
	{
		if(cmp_hdrname_strzn(&hdr->name, "Subscription-State", 18)==0)  
		{
			found = 1;
			break;
		}
		hdr = hdr->next;
	}
	if(found==0 )
	{
		LM_ERR("'Subscription-State' header not found\n");
		goto error;
	}
	auth_state = hdr->body;

	/* extract state and reason */
	auth_flag= parse_subs_state(auth_state, &reason, &expires);
	if(auth_flag< 0)
	{
		LM_ERR("while parsing 'Subscription-State' header\n");
		goto error;
	}
	if(pua_get_record_id(&dialog, &res_id)< 0) /* verify if within a stored dialog */
	{
		LM_ERR("occured when trying to get record id\n");
		goto error;
	}
	if(res_id==0)
	{
		LM_DBG("presence dialog record not found\n");
		/* if it is a NOTIFY for a terminated SUBSCRIBE dialog in RLS, then
		 * the module might not have the dialog structure anymore
		 * - just send 200ok, it is harmless
		 */
		if(auth_flag==TERMINATED_STATE)
			goto done;
		LM_INFO("no presence dialog record for non-TERMINATED state uri pres_uri = %.*s watcher_uri = %.*s\n",
                dialog.pres_uri->len, dialog.pres_uri->s, dialog.watcher_uri->len, dialog.watcher_uri->s);
		reply_code = 481;
		reply_str = pu_481_rpl;
		goto error;
	}
		
	if(msg->content_type== NULL || msg->content_type->body.s== NULL)
	{
		LM_DBG("cannot find content type header header\n");
	}
	else
		content_type= msg->content_type->body;
					
	/*constructing the xml body*/
	if(get_content_length(msg) == 0 )
	{	
		goto done;
	}	
	else
	{
		if(content_type.s== 0)
		{
			LM_ERR("content length != 0 and no content type header found\n");
			goto error;
		}
		body.s=get_body(msg);
		if (body.s== NULL) 
		{
			LM_ERR("cannot extract body from msg\n");
			goto error;
		}
		body.len = get_content_length( msg );

	}
	/* update in rlpres_table where rlsusb_did= res_id and resource_uri= from_uri*/

	LM_DBG("body= %.*s\n", body.len, body.s);

	query_cols[n_query_cols]= &str_rlsubs_did_col;
	query_vals[n_query_cols].type = DB1_STR;
	query_vals[n_query_cols].nul = 0;
	query_vals[n_query_cols].val.str_val= *res_id; 
	n_query_cols++;

	query_cols[n_query_cols]= &str_resource_uri_col;
	query_vals[n_query_cols].type = DB1_STR;
	query_vals[n_query_cols].nul = 0;
	query_vals[n_query_cols].val.str_val= *dialog.pres_uri; 
	n_query_cols++;

	query_cols[n_query_cols]= &str_updated_col;
	query_vals[n_query_cols].type = DB1_INT;
	query_vals[n_query_cols].nul = 0;
	if (dbmode == RLS_DB_ONLY)
		query_vals[n_query_cols].val.int_val=
			core_hash(res_id, NULL, 0) %
				(waitn_time * rls_notifier_poll_rate
					* rls_notifier_processes);
	else
		query_vals[n_query_cols].val.int_val = UPDATED_TYPE;
	n_query_cols++;
		
	query_cols[n_query_cols]= &str_auth_state_col;
	query_vals[n_query_cols].type = DB1_INT;
	query_vals[n_query_cols].nul = 0;
	query_vals[n_query_cols].val.int_val= auth_flag; 
	n_query_cols++;

	query_cols[n_query_cols]= &str_reason_col;
	query_vals[n_query_cols].type = DB1_STR;
	query_vals[n_query_cols].nul = 0;
	if(reason.len > 0)
	{
		query_vals[n_query_cols].val.str_val.s= reason.s;
		query_vals[n_query_cols].val.str_val.len= reason.len;
	}	
	else
	{
		query_vals[n_query_cols].val.str_val.s = "";
		query_vals[n_query_cols].val.str_val.len = 0;
	}
	n_query_cols++;

	query_cols[n_query_cols]= &str_content_type_col;
	query_vals[n_query_cols].type = DB1_STR;
	query_vals[n_query_cols].nul = 0;
	query_vals[n_query_cols].val.str_val= content_type;
	n_query_cols++;
			
	query_cols[n_query_cols]= &str_presence_state_col;
	query_vals[n_query_cols].type = DB1_STR;
	query_vals[n_query_cols].nul = 0;
	query_vals[n_query_cols].val.str_val= body;
	n_query_cols++;
		
	query_cols[n_query_cols]= &str_expires_col;
	query_vals[n_query_cols].type = DB1_INT;
	query_vals[n_query_cols].nul = 0;
	query_vals[n_query_cols].val.int_val= expires+ (int)time(NULL);
	n_query_cols++;

	if (rlpres_dbf.use_table(rlpres_db, &rlpres_table) < 0) 
	{
		LM_ERR("in use_table\n");
		goto error;
	}

	if (dbmode == RLS_DB_ONLY && rlpres_dbf.start_transaction)
	{
		if (rlpres_dbf.start_transaction(rlpres_db) < 0)
		{
			LM_ERR("in start_transaction\n");
			goto error;
		}
	}

	if (rlpres_dbf.replace != NULL)
	{
		if(rlpres_dbf.replace(rlpres_db, query_cols, query_vals, n_query_cols,
					2, 0)< 0)
		{
			LM_ERR("in sql replace\n");
			goto error;
		}
		LM_DBG("Inserted/replace in database table new record\n");
	}
	else
	{
		if(rlpres_dbf.update(rlpres_db, query_cols, 0, query_vals, query_cols+2,
						query_vals+2, 2, n_query_cols-2)< 0)
		{
			LM_ERR("in sql update\n");
			goto error;
		}

		if (rlpres_dbf.affected_rows(rlpres_db) == 0)
		{
			if(rlpres_dbf.insert(rlpres_db, query_cols, query_vals, n_query_cols)< 0)
			{
				LM_ERR("in sql insert\n");
				goto error;
			}
			LM_DBG("Inserted in database table new record\n");
		}
	}

	if (dbmode == RLS_DB_ONLY && rlpres_dbf.end_transaction)
	{
		if (rlpres_dbf.end_transaction(rlpres_db) < 0)
		{
			LM_ERR("in end_transaction\n");
			goto error;
		}
	}

	LM_DBG("Updated rlpres_table\n");	
	/* reply 200OK */
done:
	if(slb.freply(msg, 200, &su_200_rpl) < 0)
	{
		LM_ERR("while sending reply\n");
		goto error;
	}

	if(res_id!=NULL)
	{
		pkg_free(res_id->s);
		pkg_free(res_id);
	}

	if (reason.s) pkg_free(reason.s);

	free_to_params(&TO);
	return 1;

error:
	if(slb.freply(msg, reply_code, &reply_str) < 0)
	{
		LM_ERR("failed sending reply\n");
	}
	if(res_id!=NULL)
	{
		pkg_free(res_id->s);
		pkg_free(res_id);
	}

	if (reason.s) pkg_free(reason.s);

	free_to_params(&TO);

	if (dbmode == RLS_DB_ONLY && rlpres_dbf.abort_transaction)
	{
		if (rlpres_dbf.abort_transaction(rlpres_db) < 0)
			LM_ERR("in abort_transaction\n");
	}

	return -1;
}
Ejemplo n.º 16
0
static int cmd_send_message(struct sip_msg* msg, char* _foo, char* _bar)
{
	str body, from_uri, dst, tagid;
	int mime;

	LM_DBG("cmd_send_message\n");

	/* extract body */
	if (get_body(msg,&body)!=0 || body.len==0) {
		LM_ERR("failed to extract body\n");
		return -1;
	}
	if ((mime = parse_content_type_hdr(msg)) < 1) {
		LM_ERR("failed parse content-type\n");
		return -1;
	}
	if (mime != (TYPE_TEXT << 16) + SUBTYPE_PLAIN
			&& mime != (TYPE_MESSAGE << 16) + SUBTYPE_CPIM) {
		LM_ERR("invalid content-type 0x%x\n", mime);
		return -1;
	}

	/* extract sender */
	if (parse_headers(msg, HDR_TO_F | HDR_FROM_F, 0) == -1 || !msg->to
			|| !msg->from) {
		LM_ERR("no To/From headers\n");
		return -1;
	}
	if (parse_from_header(msg) < 0 || !msg->from->parsed) {
		LM_ERR("failed to parse From header\n");
		return -1;
	}

	from_uri.s = uri_sip2xmpp(&((struct to_body *) msg->from->parsed)->uri);
	from_uri.len = strlen(from_uri.s);

	tagid = ((struct to_body *) msg->from->parsed)->tag_value;
	LM_DBG("message from <%.*s>\n", from_uri.len, from_uri.s);

	/* extract recipient */
	dst.len = 0;
	if (msg->new_uri.len > 0) {
		LM_DBG("using new URI as destination\n");
		dst = msg->new_uri;
	} else if (msg->first_line.u.request.uri.s
			&& msg->first_line.u.request.uri.len > 0) {
		LM_DBG("using R-URI as destination\n");
		dst = msg->first_line.u.request.uri;
	} else if (msg->to->parsed) {
		LM_DBG("using TO-URI as destination\n");
		dst = ((struct to_body *) msg->to->parsed)->uri;
	} else {
		LM_ERR("failed to find a valid destination\n");
		return -1;
	}
	dst.s = dst.s + 4;
	dst.len = dst.len - 4;

	if (!xmpp_send_pipe_cmd(XMPP_PIPE_SEND_MESSAGE, &from_uri, &dst, &body,
				&tagid))
		return 1;
	return -1;
}
Ejemplo n.º 17
0
int bla_handle_notify(struct sip_msg* msg, char* s1, char* s2)
{
	publ_info_t publ;
	struct to_body *pto= NULL, TO, *pfrom = NULL;
	str body;
	ua_pres_t dialog;
	unsigned int expires= 0;
	struct hdr_field* hdr;
	str subs_state;
	str extra_headers= {0, 0};
	static char buf[255];
	str contact;

	memset(&publ, 0, sizeof(publ_info_t));
	memset(&dialog, 0, sizeof(ua_pres_t));

	if ( parse_headers(msg,HDR_EOH_F, 0)==-1 )
	{
		LM_ERR("parsing headers\n");
		return -1;
	}

	if( msg->to==NULL || msg->to->body.s==NULL)
	{
		LM_ERR("cannot parse TO header\n");
		return -1;
	}
	/* examine the to header */
	if(msg->to->parsed != NULL)
	{
		pto = (struct to_body*)msg->to->parsed;
		LM_DBG("'To' header ALREADY PARSED: <%.*s>\n",
				pto->uri.len, pto->uri.s );
	}
	else
	{
		parse_to(msg->to->body.s,msg->to->body.s + msg->to->body.len + 1, &TO);
		if(TO.uri.len <= 0)
		{
			LM_DBG("'To' header NOT parsed\n");
			return -1;
		}
		pto = &TO;
	}
	publ.pres_uri= &pto->uri;
	dialog.watcher_uri= publ.pres_uri;

	if (pto->tag_value.s==NULL || pto->tag_value.len==0 )
	{
		LM_ERR("NULL to_tag value\n");
		return -1;
	}
	dialog.from_tag= pto->tag_value;

	if( msg->callid==NULL || msg->callid->body.s==NULL)
	{
		LM_ERR("cannot parse callid header\n");
		return -1;
	}
	dialog.call_id = msg->callid->body;

	if (!msg->from || !msg->from->body.s)
	{
		LM_ERR("cannot find 'from' header!\n");
		return -1;
	}
	if (msg->from->parsed == NULL)
	{
		LM_DBG(" 'From' header not parsed\n");
		/* parsing from header */
		if ( parse_from_header( msg )<0 )
		{
			LM_DBG(" ERROR cannot parse From header\n");
			return -1;
		}
	}
	pfrom = (struct to_body*)msg->from->parsed;
	dialog.to_uri= pfrom->uri;

	if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0)
	{
		LM_ERR("no from tag value present\n");
		return -1;
	}
	if ( get_content_length(msg) == 0 )
	{
		LM_DBG("content length= 0\n");
		return 1;
	}
	else
	{
		body.s=get_body(msg);
		if (body.s== NULL)
		{
			LM_ERR("cannot extract body from msg\n");
			return -1;
		}
		body.len = get_content_length( msg );

		if (!bla_body_is_valid( &body ))
		{
			LM_ERR("bad XML body!");
			return -1;
		}
	}
   	
	if(msg->contact== NULL || msg->contact->body.s== NULL)
	{
		LM_ERR("no contact header found");
		return -1;
	}
	if( parse_contact(msg->contact) <0 )
	{
		LM_ERR(" cannot parse contact header\n");
		return -1;
	}

	if(msg->contact->parsed == NULL)
	{
		LM_ERR("cannot parse contact header\n");
		return -1;
	}
	contact = ((contact_body_t* )msg->contact->parsed)->contacts->uri;

	dialog.to_tag= pfrom->tag_value;
	dialog.event= BLA_EVENT;
	dialog.flag= BLA_SUBSCRIBE;
	if(pua_is_dialog(&dialog)< 0)
	{
		LM_ERR("Notify in a non existing dialog\n");
		return -2;
	}

	/* parse Subscription-State and extract expires if existing */
	hdr = get_header_by_static_name( msg, "Subscription-State");
	if( hdr==NULL )
	{
		LM_ERR("No Subscription-State header found\n");
		return -1;
	}
	subs_state= hdr->body;
	if(strncasecmp(subs_state.s, "terminated", 10)== 0)
		expires= 0;
	else
	{
		if(strncasecmp(subs_state.s, "active", 6)== 0 ||
				strncasecmp(subs_state.s, "pending", 7)==0 )
		{
			expires = DEFAULT_EXPIRES;
			char* sep= NULL;
			str exp= {NULL, 0};
			sep= strchr(subs_state.s, ';');
			if(sep)
			{
				if(strncasecmp(sep+1, "expires=", 8)== 0)
				{
					exp.s= sep+ 9;
					sep= exp.s;
					while((*sep)>='0' && (*sep)<='9')
					{
						sep++;
						exp.len++;
					}
					if( str2int(&exp, &expires)< 0)
					{
						LM_ERR("while parsing int\n");
						return -1;
					}
				}
			}
		}
		else
		{
			LM_ERR("unknown Subscription-state token\n");
			return -1;
		}
	}

	/* +2 for ": " between header name and value */
	if ((header_name.len + 2 + contact.len + CRLF_LEN) >= sizeof(buf)) {
		LM_ERR("Sender header too large");
		return -1;
	}

	/* build extra_headers with Sender*/
	extra_headers.s= buf;
	memcpy(extra_headers.s, header_name.s, header_name.len);
	extra_headers.len= header_name.len;
	memcpy(extra_headers.s+extra_headers.len,": ",2);
	extra_headers.len+= 2;
	memcpy(extra_headers.s+ extra_headers.len, contact.s, contact.len);
	extra_headers.len+= contact.len;
	memcpy(extra_headers.s+ extra_headers.len, CRLF, CRLF_LEN);
	extra_headers.len+= CRLF_LEN;

	publ.id= contact;
	publ.body= &body;
	publ.source_flag= BLA_PUBLISH;
	publ.expires= expires;
	publ.event= BLA_EVENT;
	publ.extra_headers= &extra_headers;
	publ.outbound_proxy = presence_server;

	if(pua_send_publish(&publ)< 0)
	{
		LM_ERR("failed to send Publish message\n");
		return -1;
	}

	return 1;
}
Ejemplo n.º 18
0
/**
 * store message
 * mode = "0" -- look for outgoing URI starting with new_uri
 * 		= "1" -- look for outgoing URI starting with r-uri
 * 		= "2" -- look for outgoing URI only at to header
 */
static int m_store(struct sip_msg* msg, char* mode, char* str2)
{
	str body, str_hdr, sruri, ctaddr;
	struct to_body to, *pto, *pfrom;
	db_key_t db_keys[NR_KEYS];
	db_val_t db_vals[NR_KEYS];
	int nr_keys = 0, val, lexpire;
	t_content_type ctype;
	char buf[512], buf1[1024], *p;
	int mime;

	DBG("MSILO: m_store: ------------ start ------------\n");

	// extract message body - after that whole SIP MESSAGE is parsed
	/* get the message's body */
	body.s = get_body( msg );
	if (body.s==0) 
	{
		LOG(L_ERR,"MSILO:m_store: ERROR cannot extract body from msg\n");
		goto error;
	}
	
	/* content-length (if present) must be already parsed */
	if (!msg->content_length) 
	{
		LOG(L_ERR,"MSILO:m_store: ERROR no Content-Length header found!\n");
		goto error;
	}
	body.len = get_content_length( msg );

	// check if the body of message contains something
	if(body.len <= 0)
	{
		DBG("MSILO:m_store: body of the message is empty!\n");
		goto error;
	}
	
	// check TO header
	if(!msg->to || !msg->to->body.s)
	{
		DBG("MSILO:m_store: cannot find 'to' header!\n");
		goto error;
	}

	if(msg->to->parsed != NULL)
	{
		pto = (struct to_body*)msg->to->parsed;
		DBG("MSILO:m_store: 'To' header ALREADY PARSED: <%.*s>\n",
			pto->uri.len, pto->uri.s );	
	}
	else
	{
		DBG("MSILO:m_store: 'To' header NOT PARSED ->parsing ...\n");
		memset( &to , 0, sizeof(to) );
		parse_to(msg->to->body.s, msg->to->body.s+msg->to->body.len+1, &to);
		if(to.uri.len > 0) // && to.error == PARSE_OK)
		{
			DBG("MSILO:m_store: 'To' parsed OK <%.*s>.\n", 
				to.uri.len, to.uri.s);
			pto = &to;
		}
		else
		{
			DBG("MSILO:m_store: ERROR 'To' cannot be parsed\n");
			goto error;
		}
	}
	
	if(pto->uri.len == reg_addr.len && 
			!strncasecmp(pto->uri.s, reg_addr.s, reg_addr.len))
	{
		DBG("MSILO:m_store: message to MSILO REGISTRAR!\n");
		goto error;
	}

	db_keys[nr_keys] = DB_KEY_TO;
	
	db_vals[nr_keys].type = DB_STR;
	db_vals[nr_keys].nul = 0;
	db_vals[nr_keys].val.str_val.s = pto->uri.s;
	db_vals[nr_keys].val.str_val.len = pto->uri.len;

	nr_keys++;

	// check FROM header
	if(!msg->from || !msg->from->body.s)
	{
		DBG("MSILO:m_store: ERROR cannot find 'from' header!\n");
		goto error;
	}

	if(msg->from->parsed != NULL)
		DBG("MSILO:m_store: 'From' header ALREADY PARSED\n");	
	else
	{
		DBG("MSILO:m_store: 'From' header NOT PARSED\n");
		/* parsing from header */
		if ( parse_from_header( msg )==-1 ) 
		{
			DBG("MSILO:m_store: ERROR cannot parse FROM header\n");
			goto error;
		}
	}
	pfrom = (struct to_body*)msg->from->parsed;
	DBG("MSILO:m_store: 'From' header: <%.*s>\n",pfrom->uri.len,pfrom->uri.s);	
	
	if(reg_addr.s && pfrom->uri.len == reg_addr.len && 
			!strncasecmp(pfrom->uri.s, reg_addr.s, reg_addr.len))
	{
		DBG("MSILO:m_store: message from MSILO REGISTRAR!\n");
		goto error;
	}

	db_keys[nr_keys] = DB_KEY_FROM;
	
	db_vals[nr_keys].type = DB_STR;
	db_vals[nr_keys].nul = 0;
	db_vals[nr_keys].val.str_val.s = pfrom->uri.s;
	db_vals[nr_keys].val.str_val.len = pfrom->uri.len;

	nr_keys++;

	// chech for RURI
	sruri.len = 0;
	if(mode && mode[0]=='0' && msg->new_uri.len > 0)
	{
		DBG("MSILO:m_store: NEW R-URI found - check if is AoR!\n");
		p = msg->new_uri.s;
		while((p < msg->new_uri.s+msg->new_uri.len) && *p!='@')
			p++;
		if(p < msg->new_uri.s+msg->new_uri.len && p > msg->new_uri.s)
		{
			DBG("MSILO:m_store: NEW R-URI used\n");
			sruri.s = msg->new_uri.s;
			// check for parameters
			while((p < msg->new_uri.s+msg->new_uri.len) && *p!=';')
				p++;
			sruri.len = p - msg->new_uri.s;
		}
	}
	
	if(mode && mode[0]<='1' && sruri.len == 0 
			&& msg->first_line.u.request.uri.len > 0 )
	{
		DBG("MSILO:m_store: R-URI found - check if is AoR!\n");
		p = msg->first_line.u.request.uri.s;
		while((p < msg->first_line.u.request.uri.s+
				msg->first_line.u.request.uri.len) && *p!='@')
			p++;
		if(p<msg->first_line.u.request.uri.s+msg->first_line.u.request.uri.len
			&& p > msg->first_line.u.request.uri.s)
		{
			DBG("MSILO:m_store: R-URI used\n");
			sruri.s = msg->first_line.u.request.uri.s;
			// check for parameters
			while((p < msg->first_line.u.request.uri.s
					+ msg->first_line.u.request.uri.len) && *p!=';')
				p++;
			sruri.len = p - msg->first_line.u.request.uri.s;
		}
	}
	
	if (sruri.len == 0)
	{
		DBG("MSILO:m_store: TO used as R-URI\n");
		sruri.s = pto->uri.s;
		sruri.len = pto->uri.len;
	}
	
	db_keys[nr_keys] = DB_KEY_RURI;
	
	db_vals[nr_keys].type = DB_STR;
	db_vals[nr_keys].nul = 0;
	db_vals[nr_keys].val.str_val.s = sruri.s;
	db_vals[nr_keys].val.str_val.len = sruri.len;

	nr_keys++;

	/* add the message's body in SQL query */
	
	db_keys[nr_keys] = DB_KEY_BODY;
	
	db_vals[nr_keys].type = DB_BLOB;
	db_vals[nr_keys].nul = 0;
	db_vals[nr_keys].val.blob_val.s = body.s;
	db_vals[nr_keys].val.blob_val.len = body.len;

	nr_keys++;
	
	lexpire = expire_time;
	// add 'content-type'
	/* parse the content-type header */
	if ((mime=parse_content_type_hdr(msg))<1 ) 
	{
		LOG(L_ERR,"MSILO:m_store: ERROR cannot parse Content-Type header\n");
		goto error;
	}

	/** check the content-type value */
	if( mime!=(TYPE_TEXT<<16)+SUBTYPE_PLAIN
		&& mime!=(TYPE_MESSAGE<<16)+SUBTYPE_CPIM )
	{
		if(m_extract_content_type(msg->content_type->body.s, 
				msg->content_type->body.len, &ctype, CT_TYPE) != -1)
		{
			DBG("MSILO:m_store: 'content-type' found\n");
			db_keys[nr_keys] = DB_KEY_CTYPE;
			db_vals[nr_keys].type = DB_STR;
			db_vals[nr_keys].nul = 0;
			db_vals[nr_keys].val.str_val.s = ctype.type.s;
			db_vals[nr_keys].val.str_val.len = ctype.type.len;
			nr_keys++;
		}
	}

	// check 'expires'
	// no more parseing - already done by get_body()
	// if(parse_headers(msg, HDR_EXPIRES,0)!=-1)
	if(msg->expires && msg->expires->body.len > 0)
	{
		DBG("MSILO:m_store: 'expires' found\n");
		val = atoi(msg->expires->body.s);
		if(val > 0)
			lexpire = (expire_time<=val)?expire_time:val;
	}

	/** current time */
	val = (int)time(NULL);
	
	/** add expiration time */
	db_keys[nr_keys] = DB_KEY_EXP_TIME;
	db_vals[nr_keys].type = DB_INT;
	db_vals[nr_keys].nul = 0;
	db_vals[nr_keys].val.int_val = val+lexpire;
	nr_keys++;

	/** add incoming time */
	db_keys[nr_keys] = DB_KEY_INC_TIME;
	db_vals[nr_keys].type = DB_INT;
	db_vals[nr_keys].nul = 0;
	db_vals[nr_keys].val.int_val = val;
	nr_keys++;

	if(db_insert(db_con, db_keys, db_vals, nr_keys) < 0)
	{
		LOG(L_ERR, "MSILO:m_store: error storing message\n");
		goto error;
	}
	DBG("MSILO:m_store: message stored. T:<%.*s> F:<%.*s>\n",
		pto->uri.len, pto->uri.s, pfrom->uri.len, pfrom->uri.s);
	if(reg_addr.len > 0 && reg_addr.len+33+2*CRLF_LEN < 1024)
	{
		DBG("MSILO:m_store: sending info message.\n");
		strcpy(buf1,"Content-Type: text/plain"CRLF"Contact: ");
		str_hdr.len = 24 + CRLF_LEN + 9;
		strncat(buf1,reg_addr.s,reg_addr.len);
		str_hdr.len += reg_addr.len;
		strcat(buf1, CRLF);
		str_hdr.len += CRLF_LEN;
		str_hdr.s = buf1;
	
		strncpy(buf, "User [", 6);
		body.len = 6;
		if(pto->uri.len+75 < 512)
		{
			strncpy(buf+body.len, pto->uri.s, pto->uri.len);
			body.len += pto->uri.len;
		}
		strncpy(buf+body.len, "] is offline.", 13);
		body.len += 12;
		strncpy(buf+body.len, " The message will be delivered", 30);
		body.len += 30;
		strncpy(buf+body.len, " when user goes online.", 23);
		body.len += 23;

		body.s = buf;

		// look for Contact header
		ctaddr.s = NULL;
		if(use_contact && parse_headers(msg,HDR_CONTACT,0)!=-1 && msg->contact
				&& msg->contact->body.s && msg->contact->body.len>0)
		{
			ctaddr.s = msg->contact->body.s;
			ctaddr.len = msg->contact->body.len;
			p = ctaddr.s;
			while(p<ctaddr.s+ctaddr.len && *p!='<')
				p++;
			if(*p == '<')
			{
				p++;
				ctaddr.s = p;
				while(p<ctaddr.s+ctaddr.len && *p!='>')
						p++;
				if(p<ctaddr.s+ctaddr.len)
					ctaddr.len = p-ctaddr.s;
			}
			if(!ctaddr.s || ctaddr.len < 6 || strncmp(ctaddr.s, "sip:", 4)
				|| ctaddr.s[4]==' ')
				ctaddr.s = NULL;
			else
				DBG("MSILO:m_store: feedback contact [%.*s]\n",
							ctaddr.len,ctaddr.s);
		}
		
		// tmb.t_uac(&msg_type,&pfrom->uri,&str_hdr,&body,&reg_addr,0,0,0);
		tmb.t_request(&msg_type,  /* Type of the message */
				(ctaddr.s)?&ctaddr:&pfrom->uri,    /* Request-URI */
				&pfrom->uri,      /* To */
				&reg_addr,        /* From */
				&str_hdr,         /* Optional headers including CRLF */
				&body,            /* Message body */
				NULL,             /* Callback function */
				NULL              /* Callback parameter */
			);
	}
	
	return 1;
error:
	return -1;
}
Ejemplo n.º 19
0
/**
 * sngtc_offer - will remove the SDP body of an early negotiation INVITE and
 * store it in the newly created dialog as a dlg_val.
 *
 * @return: 1 on success, negative on failure
 */
static int sngtc_offer(struct sip_msg *msg)
{
	struct hdr_field *hf;
	struct lump *lump;
	struct dlg_cell *dlg;
	struct sngtc_info *info = NULL;
	str body, totag, st;

	if (dlg_binds.create_dlg(msg, 0) < 0) {
		LM_ERR("failed to create dialog\n");
		return SNGTC_ERR;
	}

	dlg = dlg_binds.get_dlg();
	if (!dlg) {
		LM_ERR("failed to fetch current dialog\n");
		return SNGTC_ERR;
	}

	if (get_body(msg, &body) != 0 || body.len <= 0) {
		LM_ERR("can only do transcoding for early negotiation INVITES\n");
		return SNGTC_SDP_ERR;
	}

	totag = get_to(msg)->tag_value;

	/* INVITE retransmissions will skip this part */
	if (dlg_binds.fetch_dlg_value(dlg, &dlg_key_sngtc_info, &st, 0) != 0) {

		if (store_sngtc_info(dlg, &body) != 0) {
			LM_ERR("failed to create sngtc info struct\n");
			return SNGTC_ERR;
		}

		/* register a callback to free the above */
		if (dlg_binds.register_dlgcb(dlg,
			                         DLGCB_EXPIRED|DLGCB_FAILED|DLGCB_TERMINATED,
		    sngtc_dlg_terminated, NULL, NULL) != 0) {

			LM_ERR("failed to register dialog callback\n");
			return SNGTC_ERR;
		}

	/* for re-INVITES, just recreate the struct sngtc_info */
	} else if (totag.s && totag.len != 0) {
		info = *(struct sngtc_info **)(st.s);

		free_transcoding_sessions(info->sessions);
		if (info->caller_sdp.s)
			shm_free(info->caller_sdp.s);
		if (info->modified_caller_sdp.s)
			shm_free(info->modified_caller_sdp.s);

		if (store_sngtc_info(dlg, &body) != 0) {
			LM_ERR("failed to create sngtc info struct\n");
			return SNGTC_ERR;
		}

		shm_free(info);
	}

	LM_DBG("SDP body:\n");
	LM_DBG("%.*s\n", body.len, body.s);

	hf = msg->content_type;

	/* delete the Content-Type header, we're setting up late negotiation */
	lump = del_lump(msg, hf->name.s - msg->buf, hf->len, HDR_OTHER_T);
	if (!lump) {
		LM_ERR("no more pkg mem\n");
		return SNGTC_ERR;
	}

	/* trim the entire SDP body */
	lump = del_lump(msg, body.s - msg->buf, body.len, HDR_OTHER_T);
	if (!lump) {
		LM_ERR("no more pkg mem\n");
		return SNGTC_ERR;
	}

	return 1;
}
Ejemplo n.º 20
0
/**
* @brief ht dmq callback
*/
int dlg_dmq_handle_msg(struct sip_msg* msg, peer_reponse_t* resp, dmq_node_t* node)
{
	int content_length;
	str body;
	dlg_cell_t *dlg;
	int unref = 0;
	int ret;
	srjson_doc_t jdoc, prof_jdoc;
	srjson_t *it = NULL;

	dlg_dmq_action_t action = DLG_DMQ_NONE;
	dlg_iuid_t iuid;
	str profiles = {0, 0}, callid = {0, 0}, tag1 = {0,0}, tag2 = {0,0},
		contact1 = {0,0}, contact2 = {0,0}, k={0,0}, v={0,0};
	str cseq1 = {0,0}, cseq2 = {0,0}, route_set1 = {0,0}, route_set2 = {0,0},
		from_uri = {0,0}, to_uri = {0,0}, req_uri = {0,0};
	unsigned int init_ts = 0, start_ts = 0, lifetime = 0;
	unsigned int state = 1;
	srjson_t *vj;

	/* received dmq message */
	LM_DBG("dmq message received\n");

	if(!msg->content_length) {
		LM_ERR("no content length header found\n");
		goto invalid2;
	}
	content_length = get_content_length(msg);
	if(!content_length) {
		LM_DBG("content length is 0\n");
		goto invalid2;
	}

	body.s = get_body(msg);
	body.len = content_length;

	if (!body.s) {
		LM_ERR("unable to get body\n");
		goto error;
	}

	/* parse body */
	LM_DBG("body: %.*s\n", body.len, body.s);

	srjson_InitDoc(&jdoc, NULL);
	jdoc.buf = body;

	if(jdoc.root == NULL) {
		jdoc.root = srjson_Parse(&jdoc, jdoc.buf.s);
		if(jdoc.root == NULL)
		{
			LM_ERR("invalid json doc [[%s]]\n", jdoc.buf.s);
			goto invalid;
		}
	}

	for(it=jdoc.root->child; it; it = it->next)
	{
		if ((it->string == NULL) || (strcmp(it->string, "vars")==0)) continue;

		LM_DBG("found field: %s\n", it->string);

		if (strcmp(it->string, "action")==0) {
			action = SRJSON_GET_UINT(it);
		} else if (strcmp(it->string, "h_entry")==0) {
			iuid.h_entry = SRJSON_GET_UINT(it);
		} else if (strcmp(it->string, "h_id")==0) {
			iuid.h_id = SRJSON_GET_UINT(it);
		} else if (strcmp(it->string, "init_ts")==0) {
			init_ts = SRJSON_GET_UINT(it);
		} else if (strcmp(it->string, "start_ts")==0) {
			start_ts = SRJSON_GET_UINT(it);
		} else if (strcmp(it->string, "state")==0) {
			state = SRJSON_GET_UINT(it);
		} else if (strcmp(it->string, "lifetime")==0) {
			lifetime = SRJSON_GET_UINT(it);
		} else if (strcmp(it->string, "callid")==0) {
			callid.s = it->valuestring;
			callid.len = strlen(callid.s);
		} else if (strcmp(it->string, "profiles")==0) {
			profiles.s = it->valuestring;
			profiles.len = strlen(profiles.s);
		} else if (strcmp(it->string, "tag1")==0) {
			tag1.s = it->valuestring;
			tag1.len = strlen(tag1.s);
		} else if (strcmp(it->string, "tag2")==0) {
			tag2.s = it->valuestring;
			tag2.len = strlen(tag2.s);
		} else if (strcmp(it->string, "cseq1")==0) {
			cseq1.s = it->valuestring;
			cseq1.len = strlen(cseq1.s);
		} else if (strcmp(it->string, "cseq2")==0) {
			cseq2.s = it->valuestring;
			cseq2.len = strlen(cseq2.s);
		} else if (strcmp(it->string, "route_set1")==0) {
			route_set1.s = it->valuestring;
			route_set1.len = strlen(route_set1.s);
		} else if (strcmp(it->string, "route_set2")==0) {
			route_set2.s = it->valuestring;
			route_set2.len = strlen(route_set2.s);
		} else if (strcmp(it->string, "contact1")==0) {
			contact1.s = it->valuestring;
			contact1.len = strlen(contact1.s);
		} else if (strcmp(it->string, "contact2")==0) {
			contact2.s = it->valuestring;
			contact2.len = strlen(contact2.s);
		} else if (strcmp(it->string, "from_uri")==0) {
			from_uri.s = it->valuestring;
			from_uri.len = strlen(from_uri.s);
		} else if (strcmp(it->string, "to_uri")==0) {
			to_uri.s = it->valuestring;
			to_uri.len = strlen(to_uri.s);
		} else if (strcmp(it->string, "req_uri")==0) {
			req_uri.s = it->valuestring;
			req_uri.len = strlen(req_uri.s);
		} else {
			LM_ERR("unrecognized field in json object\n");
		}
	}

	dlg = dlg_get_by_iuid(&iuid);
	if (dlg) {
		LM_DBG("found dialog [%u:%u] at %p\n", iuid.h_entry, iuid.h_id, dlg);
		unref++;
	}

	switch(action) {
		case DLG_DMQ_UPDATE:
			LM_DBG("Updating dlg [%u:%u] with callid [%.*s]\n", iuid.h_entry, iuid.h_id,
					callid.len, callid.s);
			if (!dlg) {
				dlg = build_new_dlg(&callid, &from_uri, &to_uri, &tag1, &req_uri);
				if (!dlg) {
					LM_ERR("failed to build new dialog\n");
					goto error;
				}

				if(dlg->h_entry != iuid.h_entry){
					LM_ERR("inconsistent hash data from peer: "
						"make sure all Kamailio's use the same hash size\n");
					shm_free(dlg);
					goto error;
				}

				/* link the dialog */
				link_dlg(dlg, 0, 0);
				dlg_set_leg_info(dlg, &tag1, &route_set1, &contact1, &cseq1, 0);
				/* override generated h_id */
				dlg->h_id = iuid.h_id;
				/* prevent DB sync */
				dlg->dflags &= ~(DLG_FLAG_NEW|DLG_FLAG_CHANGED);
				dlg->iflags |= DLG_IFLAG_DMQ_SYNC;
			} else {
				/* remove existing profiles */
				if (dlg->profile_links!=NULL) {
					destroy_linkers(dlg->profile_links);
					dlg->profile_links = NULL;
				}
			}

			dlg->init_ts = init_ts;
			dlg->start_ts = start_ts;

			vj = srjson_GetObjectItem(&jdoc, jdoc.root, "vars");
			if(vj!=NULL) {
				for(it=vj->child; it; it = it->next)
				{
					k.s = it->string;        k.len = strlen(k.s);
					v.s = it->valuestring;   v.len = strlen(v.s);
					set_dlg_variable(dlg, &k, &v);
				}
			}
			/* add profiles */
			if(profiles.s!=NULL) {
				srjson_InitDoc(&prof_jdoc, NULL);
				prof_jdoc.buf = profiles;
				dlg_json_to_profiles(dlg, &prof_jdoc);
				srjson_DestroyDoc(&prof_jdoc);
			}
			if (state == dlg->state) {
				break;
			}
			/* intentional fallthrough */

		case DLG_DMQ_STATE:
			if (!dlg) {
				LM_ERR("dialog [%u:%u] not found\n", iuid.h_entry, iuid.h_id);
				goto error;
			}
			if (state < dlg->state) {
				LM_NOTICE("Ignoring backwards state change on dlg [%u:%u]"
						" with callid [%.*s] from state [%u] to state [%u]\n",
					iuid.h_entry, iuid.h_id,
					dlg->callid.len, dlg->callid.s, dlg->state, state);
				break;
			}
			LM_DBG("State update dlg [%u:%u] with callid [%.*s] from state [%u]"
					" to state [%u]\n", iuid.h_entry, iuid.h_id,
					dlg->callid.len, dlg->callid.s, dlg->state, state);
			switch (state) {
				case DLG_STATE_EARLY:
					dlg->start_ts = start_ts;
					dlg->lifetime = lifetime;
					dlg_set_leg_info(dlg, &tag1, &route_set1, &contact1, &cseq1, 0);
					break;
				case DLG_STATE_CONFIRMED:
					dlg->start_ts = start_ts;
					dlg->lifetime = lifetime;
					dlg_set_leg_info(dlg, &tag1, &route_set1, &contact1, &cseq1, 0);
					dlg_set_leg_info(dlg, &tag2, &route_set2, &contact2, &cseq2, 1);
					if (insert_dlg_timer( &dlg->tl, dlg->lifetime ) != 0) {
						LM_CRIT("Unable to insert dlg timer %p [%u:%u]\n",
							dlg, dlg->h_entry, dlg->h_id);
					} else {
						/* dialog pointer inserted in timer list */
						dlg_ref(dlg, 1);
					}
					break;
				case DLG_STATE_DELETED:
					if (dlg->state == DLG_STATE_CONFIRMED) {
						ret = remove_dialog_timer(&dlg->tl);
						if (ret == 0) {
							/* one extra unref due to removal from timer list */
							unref++;
						} else if (ret < 0) {
							LM_CRIT("unable to unlink the timer on dlg %p [%u:%u]\n",
								dlg, dlg->h_entry, dlg->h_id);
						}
					}
					/* prevent DB sync */
					dlg->dflags |= DLG_FLAG_NEW;
					/* keep dialog around for a bit, to prevent out-of-order
					 * syncs to reestablish the dlg */
					dlg->init_ts = time(NULL);
					break;
				default:
					LM_ERR("unhandled state update to state %u\n", state);
					dlg_unref(dlg, unref);
					goto error;
			}
			dlg->state = state;
			break;

		case DLG_DMQ_RM:
			if (!dlg) {
				LM_DBG("dialog [%u:%u] not found\n", iuid.h_entry, iuid.h_id);
				goto error;
			}
			LM_DBG("Removed dlg [%u:%u] with callid [%.*s] int state [%u]\n",
					iuid.h_entry, iuid.h_id,
					dlg->callid.len, dlg->callid.s, dlg->state);
			if (dlg->state==DLG_STATE_CONFIRMED
					|| dlg->state==DLG_STATE_EARLY) {
				ret = remove_dialog_timer(&dlg->tl);
				if (ret == 0) {
					/* one extra unref due to removal from timer list */
					unref++;
				} else if (ret < 0) {
					LM_CRIT("unable to unlink the timer on dlg %p [%u:%u]\n",
						dlg, dlg->h_entry, dlg->h_id);
				}
			}
			/* prevent DB sync */
			dlg->dflags |= DLG_FLAG_NEW;
			unref++;
			break;

		case DLG_DMQ_SYNC:
			dmq_send_all_dlgs(0);
			break;

		case DLG_DMQ_NONE:
			break;
	}
	if (dlg && unref)
		dlg_unref(dlg, unref);

	srjson_DestroyDoc(&jdoc);
	resp->reason = dmq_200_rpl;
	resp->resp_code = 200;
	return 0;

invalid:
	srjson_DestroyDoc(&jdoc);
invalid2:
	resp->reason = dmq_400_rpl;
	resp->resp_code = 400;
	return 0;

error:
	srjson_DestroyDoc(&jdoc);
	resp->reason = dmq_500_rpl;
	resp->resp_code = 500;
	return 0;
}
Ejemplo n.º 21
0
int select_msg_body(str* res, select_t* s, struct sip_msg* msg)
{
	res->s = get_body(msg);
	res->len = msg->buf+msg->len - res->s;
	return 0;	
}
Ejemplo n.º 22
0
int push_on_network(struct sip_msg *msg, int net)
{
	str    body;
	struct sip_uri  uri;
	struct sms_msg  *sms_messg;
	struct to_body  *from;
	char   *p;
	int    len;
	int    mime;

	/* get the message's body
	 * anyhow we have to call this function, so let's do it at the beginning
	 * to force the parsing of all the headers - like this we avoid separate
	 * calls of parse_headers function for FROM, CONTENT_LENGTH, TO hdrs  */
	body.s = get_body( msg );
	if (body.s==0) {
		LM_ERR("failed to extract body from msg!\n");
		goto error;
	}

	/* content-length (if present) must be already parsed */
	if (!msg->content_length) {
		LM_ERR("no Content-Length header found!\n");
		goto error;
	}
	body.len = get_content_length( msg );

	/* parse the content-type header */
	if ( (mime=parse_content_type_hdr(msg))<1 ) {
		LM_ERR("failed to parse Content-Type header\n");
		goto error;
	}

	/* check the content-type value */
	if ( mime!=(TYPE_TEXT<<16)+SUBTYPE_PLAIN
	&& mime!=(TYPE_MESSAGE<<16)+SUBTYPE_CPIM ) {
		LM_ERR("invalid content-type for a message request! type found=%d\n",
				mime);
		goto error;
	}

	/* we try to get the user name (phone number) first from the RURI 
	   (in our case means from new_uri or from first_line.u.request.uri);
	   if it's missing there (like in requests generated by MSN MESSENGER),
	   we go for "to" header
	*/
	LM_DBG("string to get user from new_uri\n");
	if ( !msg->new_uri.s||parse_uri( msg->new_uri.s,msg->new_uri.len,&uri)
	|| !uri.user.len )
	{
		LM_DBG("string to get user from R_uri\n");
		if ( parse_uri( msg->first_line.u.request.uri.s,
		msg->first_line.u.request.uri.len ,&uri)||!uri.user.len )
		{
			LM_DBG("string to get user from To\n");
			if ( (!msg->to&&((parse_headers(msg,HDR_TO_F,0)==-1) ||
					!msg->to)) ||
				parse_uri( get_to(msg)->uri.s, get_to(msg)->uri.len, &uri)==-1
			|| !uri.user.len)
			{
				LM_ERR("unable to extract user name from RURI and To header!\n");
				goto error;
			}
		}
	}
	/* check the uri.user format = '+(inter code)(number)' */
	if (uri.user.len<2 || uri.user.s[0]!='+' || uri.user.s[1]<'1'
	|| uri.user.s[1]>'9') {
		LM_ERR("user tel number [%.*s] does not respect international format\n"
				,uri.user.len,uri.user.s);
		goto error;
	}

	/* parsing from header */
	if ( parse_from_header( msg )==-1 ) {
		LM_ERR("failed to get FROM header\n");
		goto error;
	}
	from = (struct to_body*)msg->from->parsed;

#if 0
	/* adds contact header into reply */
	if (add_contact(msg,&(uri.user))==-1) {
		LM_ERR("can't build contact for reply\n");
		goto error;
	}
#endif

	/*-------------BUILD AND FILL THE SMS_MSG STRUCTURE --------------------*/
	/* computes the amount of memory needed */
	len = SMS_HDR_BF_ADDR_LEN + from->uri.len
		+ SMS_HDR_AF_ADDR_LEN + body.len + SMS_FOOTER_LEN /*text to send*/
		+ from->uri.len /* from */
		+ uri.user.len-1 /* to user (without '+') */
		+ sizeof(struct sms_msg) ; /* the sms_msg structure */
	/* allocs a new sms_msg structure in shared memory */
	sms_messg = (struct sms_msg*)shm_malloc(len);
	if (!sms_messg) {
		LM_ERR("failed to get shm memory!\n");
		goto error;
	}
	p = (char*)sms_messg + sizeof(struct sms_msg);

	/* copy "from" into sms struct */
	sms_messg->from.len = from->uri.len;
	sms_messg->from.s = p;
	append_str(p,from->uri.s,from->uri.len);

	/* copy "to.user" - we have to strip out the '+' */
	sms_messg->to.len = uri.user.len-1;
	sms_messg->to.s = p;
	append_str(p,uri.user.s+1,sms_messg->to.len);

	/* copy (and composing) sms body */
	sms_messg->text.len = SMS_HDR_BF_ADDR_LEN + sms_messg->from.len
		+ SMS_HDR_AF_ADDR_LEN + body.len+SMS_FOOTER_LEN;
	sms_messg->text.s = p;
	append_str(p, SMS_HDR_BF_ADDR, SMS_HDR_BF_ADDR_LEN);
	append_str(p, sms_messg->from.s, sms_messg->from.len);
	append_str(p, SMS_HDR_AF_ADDR, SMS_HDR_AF_ADDR_LEN);
	append_str(p, body.s, body.len);
	append_str(p, SMS_FOOTER, SMS_FOOTER_LEN);

	if (*queued_msgs>MAX_QUEUED_MESSAGES)
		goto error;
	(*queued_msgs)++;

	if (write(net_pipes_in[net], &sms_messg, sizeof(sms_messg))!=
	sizeof(sms_messg) )
	{
		LM_ERR("error when writing for net %d to pipe [%d] : %s\n",
				net,net_pipes_in[net],strerror(errno) );
		shm_free(sms_messg);
		(*queued_msgs)--;
		goto error;
	}

	return 1;
 error:
	return -1;
}
Ejemplo n.º 23
0
/**
* @brief ht dmq callback
*/
int usrloc_dmq_handle_msg(struct sip_msg* msg, peer_reponse_t* resp, dmq_node_t* node)
{
	int content_length;
	str body;
	srjson_doc_t jdoc;
	srjson_t *it = NULL;
	static ucontact_info_t ci;

	int action, expires, cseq, flags, cflags, q, last_modified, methods, reg_id;
	str aor, ruid, c, received, path, callid, user_agent, instance;

	parse_from_header(msg);
	body = ((struct to_body*)msg->from->parsed)->uri;

	LM_DBG("dmq message received from %.*s\n", body.len, body.s);

	if(!msg->content_length) {
		LM_ERR("no content length header found\n");
		goto invalid;
	}
	content_length = get_content_length(msg);
	if(!content_length) {
		LM_DBG("content length is 0\n");
		goto invalid;
	}

	body.s = get_body(msg);
	body.len = content_length;

	if (!body.s) {
		LM_ERR("unable to get body\n");
		goto error;
	}

	srjson_InitDoc(&jdoc, NULL);
	jdoc.buf = body;
	if(jdoc.root == NULL) {
		jdoc.root = srjson_Parse(&jdoc, jdoc.buf.s);
		if(jdoc.root == NULL)
		{
			LM_ERR("invalid json doc [[%s]]\n", jdoc.buf.s);
			goto invalid;
		}
	}

	for(it=jdoc.root->child; it; it = it->next)
	{
		if (it->string == NULL) continue;

		if (strcmp(it->string, "action")==0) {
			action = it->valueint;
		} else if (strcmp(it->string, "aor")==0) {
			aor.s = it->valuestring;
			aor.len = strlen(aor.s);
		} else if (strcmp(it->string, "ruid")==0) {
			ruid.s = it->valuestring;
			ruid.len = strlen(ruid.s);
		} else if (strcmp(it->string, "c")==0) {
			c.s = it->valuestring;
			c.len = strlen(c.s);
		} else if (strcmp(it->string, "received")==0) {
			received.s = it->valuestring;
			received.len = strlen(received.s);
		} else if (strcmp(it->string, "path")==0) {
			path.s = it->valuestring;
			path.len = strlen(path.s);
		} else if (strcmp(it->string, "callid")==0) {
			callid.s = it->valuestring;
			callid.len = strlen(callid.s);
		} else if (strcmp(it->string, "user_agent")==0) {
			user_agent.s = it->valuestring;
			user_agent.len = strlen(user_agent.s);
		} else if (strcmp(it->string, "instance")==0) {
			instance.s = it->valuestring;
			instance.len = strlen(instance.s);
		} else if (strcmp(it->string, "expires")==0) { //
			expires = it->valueint;
		} else if (strcmp(it->string, "cseq")==0) {
			cseq = it->valueint;
		} else if (strcmp(it->string, "flags")==0) {
			flags = it->valueint;
		} else if (strcmp(it->string, "cflags")==0) {
			cflags = it->valueint;
		} else if (strcmp(it->string, "q")==0) {
			q = it->valueint;
		} else if (strcmp(it->string, "last_modified")==0) {
			last_modified = it->valueint;
		} else if (strcmp(it->string, "methods")==0) {
			methods = it->valueint;
		} else if (strcmp(it->string, "reg_id")==0) {
			reg_id = it->valueint;
		} else {
			LM_ERR("unrecognized field in json object\n");
		}
	}
	memset( &ci, 0, sizeof(ucontact_info_t));
	ci.ruid = ruid;
	ci.c = &c;
	ci.received = received;
	ci.path = &path;
	ci.expires = expires;
	ci.q = q;
	ci.callid = &callid;
	ci.cseq = cseq;
	ci.flags = flags;
	ci.flags |= FL_RPL;
	ci.cflags = cflags;
	ci.user_agent = &user_agent;
	ci.methods = methods;
	ci.instance = instance;
	ci.reg_id = reg_id;
	ci.tcpconn_id = -1;
	ci.last_modified = last_modified;

	switch(action) {
		case DMQ_UPDATE:
			LM_DBG("Received DMQ_UPDATE. Update contact info...\n");
			add_contact(aor, &ci);
			break;
		case DMQ_RM:
			LM_DBG("Received DMQ_RM. Delete contact info...\n");
			delete_contact(aor, &ci);
			break;
		case DMQ_SYNC:
			LM_DBG("Received DMQ_SYNC. Sending all contacts...\n");
			usrloc_get_all_ucontact(node);
			break;
		case DMQ_NONE:
			LM_DBG("Received DMQ_NONE. Not used...\n");
			break;
		default:
			goto invalid;
	}

	srjson_DestroyDoc(&jdoc);
	resp->reason = dmq_200_rpl;
	resp->resp_code = 200;
	return 0;

invalid:
	srjson_DestroyDoc(&jdoc);
	resp->reason = dmq_400_rpl;
	resp->resp_code = 400;
	return 0;

error:
	srjson_DestroyDoc(&jdoc);
	resp->reason = dmq_500_rpl;
	resp->resp_code = 500;
	return 0;
}
Ejemplo n.º 24
0
/**
 * manage SIP message
 */
int xjab_manage_sipmsg(struct sip_msg *msg, int type)
{
	str body, dst, from_uri;
	xj_sipmsg jsmsg;
	int pipe, fl;
	t_xj_jkey jkey, *p;
	int mime;

	body.len = 0;
	body.s = 0;

	// extract message body - after that whole SIP MESSAGE is parsed
	if (type==XJ_SEND_MESSAGE)
	{
		/* get the message's body */
		body.s = get_body( msg );
		if(body.s==0) 
		{
			LM_ERR("cannot extract body from msg\n");
			goto error;
		}
		
		/* content-length (if present) must be already parsed */
		if(!msg->content_length)
		{
			LM_ERR("no Content-Length header found!\n");
			goto error;
		}
		body.len = get_content_length(msg);

		/* parse the content-type header */
		if((mime=parse_content_type_hdr(msg))<1)
		{
			LM_ERR("cannot parse Content-Type header\n");
			goto error;
		}

		/* check the content-type value */
		if(mime!=(TYPE_TEXT<<16)+SUBTYPE_PLAIN
			&& mime!=(TYPE_MESSAGE<<16)+SUBTYPE_CPIM)
		{
			LM_ERR("invalid content-type for"
				" a message request! type found=%d\n", mime);
			goto error;
		}
	}
	
	// check for TO and FROM headers - if is not SIP MESSAGE 
	if(parse_headers(msg,HDR_TO_F|HDR_FROM_F,0)==-1 || !msg->to || !msg->from)
	{
		LM_ERR("cannot find TO or FROM HEADERS!\n");
		goto error;
	}
	
	/* parsing from header */
	if ( parse_from_header( msg )<0 || msg->from->parsed==NULL) 
	{
		LM_DBG("cannot get FROM header\n");
		goto error;
	}
	from_uri.s = ((struct to_body*)msg->from->parsed)->uri.s;
	from_uri.len = ((struct to_body*)msg->from->parsed)->uri.len;
	if(xj_extract_aor(&from_uri, 0))
	{
		LM_DBG("cannot get AoR from FROM header\n");
		goto error;
	}

	jkey.hash = xj_get_hash(&from_uri, NULL);
	jkey.id = &from_uri;
	// get the communication pipe with the worker
	switch(type)
	{
		case XJ_SEND_MESSAGE:
		case XJ_JOIN_JCONF:
		case XJ_GO_ONLINE:
			if((pipe = xj_wlist_get(jwl, &jkey, &p)) < 0)
			{
				LM_DBG("cannot find pipe of the worker!\n");
				goto error;
			}
		break;
		case XJ_EXIT_JCONF:
		case XJ_GO_OFFLINE:
			if((pipe = xj_wlist_check(jwl, &jkey, &p)) < 0)
			{
				LM_DBG("no open Jabber session for"
						" <%.*s>!\n", from_uri.len, from_uri.s);
				goto error;
			}
		break;
		default:
			LM_DBG("ERROR:strange SIP msg type!\n");
			goto error;
	}

	// if is for going ONLINE/OFFLINE we do not need the destination
	if(type==XJ_GO_ONLINE || type==XJ_GO_OFFLINE)
		goto prepare_job;
	
	// determination of destination
	// - try to get it from new_uri, r-uri or to hdr, but check it against
	// jdomain and aliases
	dst.len = 0;
	if( msg->new_uri.len > 0)
	{
		dst.s = msg->new_uri.s;
		dst.len = msg->new_uri.len;
		if(xj_wlist_check_aliases(jwl, &dst))
			dst.len = 0;
#ifdef XJ_EXTRA_DEBUG
		else
			LM_DBG("using NEW URI for destination\n");
#endif
	}
	
	if (dst.len == 0 &&  msg->first_line.u.request.uri.s != NULL
			&& msg->first_line.u.request.uri.len > 0 )
	{
		dst.s = msg->first_line.u.request.uri.s;
		dst.len = msg->first_line.u.request.uri.len;
		if(xj_wlist_check_aliases(jwl, &dst))
			dst.len = 0;
#ifdef XJ_EXTRA_DEBUG
		else
			LM_DBG("using R-URI for destination\n");
#endif
	}

	if(dst.len == 0 && msg->to->parsed)
	{
		dst.s = ((struct to_body*)msg->to->parsed)->uri.s;
		dst.len = ((struct to_body*)msg->to->parsed)->uri.len;
		if(dst.s == NULL || xj_wlist_check_aliases(jwl, &dst))
			dst.len = 0;
#ifdef XJ_EXTRA_DEBUG
		else
			LM_DBG("using TO-URI for destination\n");
#endif
	}
	
	if(dst.len == 0)
	{
		LM_DBG("destination not found in SIP message\n");
		goto error;
	}
	
	/** skip 'sip:' and parameters in destination address */
	if(xj_extract_aor(&dst, 1))
	{
		LM_ERR("cannot get AoR for destination\n");
		goto error;
	}
#ifdef XJ_EXTRA_DEBUG
	LM_DBG("destination after correction [%.*s].\n", dst.len, dst.s);
#endif
	
prepare_job:
	//putting the SIP message parts in share memory to be accessible by workers
    jsmsg = (xj_sipmsg)shm_malloc(sizeof(t_xj_sipmsg));
	memset(jsmsg, 0, sizeof(t_xj_sipmsg));
    if(jsmsg == NULL)
    	return -1;
	
	switch(type)
	{
		case XJ_SEND_MESSAGE:
			jsmsg->msg.len = body.len;
			if((jsmsg->msg.s = (char*)shm_malloc(jsmsg->msg.len+1)) == NULL)
			{
				shm_free(jsmsg);
				goto error;
			}
			strncpy(jsmsg->msg.s, body.s, jsmsg->msg.len);
		break;
		case XJ_GO_ONLINE:
		case XJ_GO_OFFLINE:
			dst.len = 0;
			dst.s = 0;
		case XJ_JOIN_JCONF:
		case XJ_EXIT_JCONF:
			jsmsg->msg.len = 0;
			jsmsg->msg.s = NULL;
		break;
		default:
			LM_DBG("this SHOULD NOT appear\n");
			shm_free(jsmsg);
			goto error;
	}
	if(dst.len>0)
	{
		jsmsg->to.len = dst.len;
		if((jsmsg->to.s = (char*)shm_malloc(jsmsg->to.len+1))==NULL)
		{
			if(type == XJ_SEND_MESSAGE)
				shm_free(jsmsg->msg.s);
			shm_free(jsmsg);
			goto error;
		}
		strncpy(jsmsg->to.s, dst.s, jsmsg->to.len);
	}
	else
	{
		jsmsg->to.len = 0;
		jsmsg->to.s   = 0;
	}

	jsmsg->jkey = p;
	jsmsg->type = type;
	//jsmsg->jkey->hash = jkey.hash;

	LM_DBG("sending <%p> to worker through <%d>\n",	jsmsg, pipe);
	// sending the SHM pointer of SIP message to the worker
	fl = write(pipe, &jsmsg, sizeof(jsmsg));
	if(fl != sizeof(jsmsg))
	{
		LM_ERR("failed to write to worker pipe!\n");
		if(type == XJ_SEND_MESSAGE)
			shm_free(jsmsg->msg.s);
		shm_free(jsmsg->to.s);
		shm_free(jsmsg);
		goto error;
	}
	
	return 1;
error:
	return -1;
}
Ejemplo n.º 25
0
int ac_cancel(as_p the_as,unsigned char processor_id,unsigned int flags,char *action,int len)
{
   unsigned int ret,cancelled_hashIdx,cancelled_label,i;
   struct sip_msg *my_msg;
   struct as_uac_param *the_param;
   struct cell* t_invite;
   int k,retval,uac_id;
   str headers,body;

   body.s=headers.s=NULL;
   my_msg=NULL;
   the_param=NULL;
   i=k=0;

   net2hostL(uac_id,action,k);

   net2hostL(cancelled_hashIdx,action,k);
   net2hostL(cancelled_label,action,k);

   if(!(headers.s=pkg_malloc(MAX_HEADER))){
      LM_ERR("Out of Memory!!");
      goto error;
   }
   headers.len=0;
   if(!(my_msg=pkg_malloc(sizeof(struct sip_msg)))){
      LM_ERR("out of memory!\n");
      goto error;
   }
   memset(my_msg,0,sizeof(struct sip_msg));
   my_msg->buf=action+k;
   my_msg->len=len-k;
   LM_DBG("Action UAC Message: uac_id:%d processor_id=%d, message:[%.*s]\n",
		   uac_id,processor_id,len-4,&action[4]);
   if(parse_msg(action+k,len-k,my_msg)<0){
      LM_ERR("parsing sip_msg");
      goto error;
   }
   if(my_msg->first_line.type==SIP_REPLY){
      LM_ERR("trying to create a UAC with a SIP response!!\n");
      goto error;
   }
   if(parse_headers(my_msg,HDR_EOH_F,0)==-1){
      LM_ERR("parsing headers\n");
      goto error;
   }
   if(0>(headers.len=extract_allowed_headers(my_msg,1,-1,HDR_CONTENTLENGTH_F|HDR_ROUTE_F|HDR_TO_F|HDR_FROM_F|HDR_CALLID_F|HDR_CSEQ_F,headers.s,MAX_HEADER))) {
      LM_ERR("Unable to extract allowed headers!!\n");
      goto error;
   }
   if(flags & SPIRAL_FLAG){
      memcpy(headers.s+headers.len,SPIRAL_HDR CRLF,SPIRAL_HDR_LEN + CRLF_LEN);
      headers.len+=SPIRAL_HDR_LEN+CRLF_LEN;
      /*headers.s[headers.len]=0;
      fake_uri.s=pkg_malloc(200);
      fake_uri.len=print_local_uri(the_as,processor_id,fake_uri.s,200);

      if(fake_uri.len<0){
	 SLM_ERR("printing local uri\n");
	 goto error;
      }
      my_dlg->hooks.next_hop=&fake_uri;*/
   }

   headers.s[headers.len]=0;

   /*let's get the body*/
   i=(unsigned int)get_content_length(my_msg);
   if(i!=0){
      if(!(body.s=pkg_malloc(i))){
	 LM_ERR("Out of Memory!");
	 goto error;
      }
      memcpy(body.s,get_body(my_msg),i);
      body.len=i;
      LM_DBG("Trying to construct a Sip Request with: body:%d[%s]"
			  " headers:%d[%s]\n", body.len,body.s,headers.len,headers.s);
   }else{
      body.s=NULL;
      body.len=0;
   }

   if(!(the_param=shm_malloc(sizeof(struct as_uac_param)))){
      LM_ERR("no more share memory\n");
      goto error;
   }

	if(seas_f.tmb.t_lookup_ident(&t_invite,cancelled_hashIdx,cancelled_label)<0){
		LM_ERR("failed to t_lookup_ident hash_idx=%d,"
			"label=%d\n", cancelled_hashIdx,cancelled_label);
		goto error;
	}
	seas_f.tmb.unref_cell(t_invite);

   the_param->who=my_as;
   the_param->uac_id=uac_id;
   the_param->processor_id=processor_id;
   the_param->destroy_cb_set=0;
   
   /* registers TMCB_RESPONSE_IN|TMCB_LOCAL_COMPLETED tm callbacks */
   ret=seas_f.tmb.t_cancel_uac(&headers,&body,cancelled_hashIdx,cancelled_label,uac_cb,(void*)the_param);
   if (ret == 0) {
      LM_ERR( "t_cancel_uac failed\n");
      as_action_fail_resp(uac_id,SE_CANCEL,SE_CANCEL_MSG,SE_CANCEL_MSG_LEN);
      goto error;
   }else{
      the_param->label=ret;
   }

	seas_f.tmb.unref_cell(t_invite);
   retval=0;
   goto exit;
error:
   retval = -1;
   if(the_param)
      shm_free(the_param);
exit:
   if(headers.s)
      pkg_free(headers.s);
   if(body.s)
      pkg_free(headers.s);
   if(my_msg){
      if(my_msg->headers)
	 free_hdr_field_lst(my_msg->headers);
      pkg_free(my_msg);
   }
   return retval;
}
Ejemplo n.º 26
0
Archivo: mu-msg.c Proyecto: akonring/mu
const char*
mu_msg_get_body_text (MuMsg *self, MuMsgOptions opts)
{
	g_return_val_if_fail (self, NULL);
	return free_later_str (self, get_body (self, opts, FALSE));
}
Ejemplo n.º 27
0
/* builds digest string of msg
   Return value: 1: success
                 0: else
    digestString must point to an array with at least MAX_DIGEST bytes
*/
static int makeDigestString(char * digestString, char * dateHF,
														struct sip_msg * msg)
{
	struct to_body * from = NULL;
	struct to_body * to = NULL;
	struct cseq_body * cseq = NULL;
	struct hdr_field * date = NULL;
	contact_t * contact = NULL;
	unsigned int l;
	str tmp;

	if(!digestString || !msg)
	{
		LM_ERR("not all parameters set\n");
		return 0;
	}

	l = 0;

	/* ###from### */
	if(parse_from_header(msg) != 0)
	{
		LM_ERR("error parsing from header\n");
		return 0;
	}

	from = get_from(msg);
	if(!from)
	{
		LM_ERR("error getting from header\n");
		return 0;
	}

	if (l+from->uri.len+1>MAX_DIGEST) {
		LM_ERR("buffer to short 1\n");
		return 0;
	}
	memcpy( digestString+l, from->uri.s, from->uri.len);
	l += from->uri.len;
	*(digestString+(l++)) = '|';

	/* ###To### */
	to = get_to(msg);
	if(!to)
	{
		LM_ERR("error getting to header\n");
		return 0;
	}

	if (l+to->uri.len+1>MAX_DIGEST) {
		LM_ERR("buffer to short 2\n");
		return 0;
	}
	memcpy( digestString+l, to->uri.s, to->uri.len);
	l += to->uri.len;
	*(digestString+(l++)) = '|';

	/* ###callid### */
	if(!msg->callid)
	{
		LM_ERR("error getting callid header\n");
		return 0;
	}

	if (l+msg->callid->body.len+1>MAX_DIGEST) {
		LM_ERR("buffer to short 3\n");
		return 0;
	}
	memcpy( digestString+l, msg->callid->body.s, msg->callid->body.len);
	l += msg->callid->body.len;
	*(digestString+(l++)) = '|';

	/* ###CSeq### */
	cseq = (struct cseq_body *)msg->cseq->parsed;
	if (!cseq)
	{
		LM_ERR("error getting cseq header\n");
		return 0;
	}

	tmp.s = cseq->number.s;
	tmp.len = cseq->number.len;

	/* strip leading zeros */
	while((*(tmp.s) == '0') && (tmp.len > 1))
	{
		(tmp.s)++;
		(tmp.len)--;
	}

	if (l+tmp.len+cseq->method.len+2>MAX_DIGEST) {
		LM_ERR("buffer to short 4\n");
		return 0;
	}
	memcpy( digestString+l, tmp.s, tmp.len);
	l += tmp.len;
	*(digestString+(l++)) = ' ';
	memcpy( digestString+l, cseq->method.s, cseq->method.len);
	l += cseq->method.len;
	*(digestString+(l++)) = '|';

	/* ###Date### */
	if(!dateHF)
	{
		/* Date header field is taken from msg: verifier */
		date = get_header_by_static_name(msg,"Date");
		if (!date)
		{
			LM_ERR("error getting date header\n");
			return 0;
		}
		tmp = date->body;
	}
	else
	{
		/* Date header field is taken from dateHF: authentication service */
		tmp.s = dateHF;
		tmp.len = strlen(tmp.s);
	}

	if (l+tmp.len+1>MAX_DIGEST) {
		LM_ERR("buffer to short 5\n");
		return 0;
	}
	memcpy( digestString+l, tmp.s, tmp.len);
	l += tmp.len;
	*(digestString+(l++)) = '|';

	/* ###Contact### */
	if(msg->contact)
	{
		if(parse_contact(msg->contact) != 0)
		{
			LM_ERR("error parsing contact header\n");
			return 0;
		}
		/* first contact in list */
		contact = ((contact_body_t *)(msg->contact->parsed))->contacts;
		tmp = contact->uri;
	} else {
		tmp.len = 0;
		tmp.s = 0;
	}

	if (l+tmp.len+1>MAX_DIGEST) {
		LM_ERR("buffer to short 6\n");
		return 0;
	}
	if (tmp.len) {
		memcpy( digestString+l, tmp.s, tmp.len);
		l += tmp.len;
	}
	*(digestString+(l++)) = '|';

	/* ###body### */
	if ( get_body(msg,&tmp)!=0 ) {
		LM_ERR("failed to inspect body\n");
		return 0;
	}
	if (tmp.len != 0) {
		if (l+tmp.len+1>MAX_DIGEST) {
			LM_ERR("buffer to short 7\n");
			return 0;
		}
		memcpy( digestString+l, tmp.s, tmp.len);
		l += tmp.len;
		*(digestString+(l++)) = 0;
	}

	LM_DBG("Digest-String=>%s<\n", digestString);
	return 1;
}
Ejemplo n.º 28
0
/**
 * ac_reply: UAS transaction Reply action. It replies to an incoming request with a response.
 * @param the_as The App Server that sent this action.
 * @param action action
 * @param len length
 *
 * function description
 *
 * Returns: what
 */
int ac_reply(as_p the_as,unsigned char processor_id,unsigned int flags,char *action,int len)
{
   unsigned int hash_index,label,contentlength;
   struct cell *c=NULL;
   struct sip_msg *my_msg;
   struct to_body *tb;
   str new_header,body,totag;
   char *ttag;
   int i,k,retval;
   static char headers[MAX_HEADER];
   struct as_uac_param *the_param;

   contentlength=0;
   ttag=NULL;
   my_msg=NULL;
   i=k=0;
   the_param=NULL;

   net2hostL(hash_index,action,k);
   net2hostL(label,action,k);

   if(seas_f.tmb.t_lookup_ident(&c,hash_index,label)<0){
      LM_ERR("Failed to t_lookup_ident hash_idx=%d,label=%d\n",hash_index,label);
      goto error;
   }
   if(use_stats)
      action_stat(c);
   if(c->uas.status>=200){
      LM_ERR("ac_reply: trying to reply to a \"%.*s\" transaction"
	    "that is already in completed state\n",REQ_LINE(c->uas.request).method.len,REQ_LINE(c->uas.request).method.s);
      goto error;
   }
   if (!(my_msg=parse_ac_msg(HDR_EOH_F,action+k,len-k))) {
      LM_ERR("Failed to parse_ac_msg hash_idx=%d,label=%d\n",hash_index,label);
      goto error;
   }
   tb=(struct to_body*)my_msg->to->parsed;
   if(tb->tag_value.s && tb->tag_value.len){
      totag=tb->tag_value;
   }else{
      totag.s=NULL;
      totag.len=0;
      /*if(!(ttag=pkg_malloc(TOTAG_VALUE_LEN))){
	 LM_ERR("Out of memory !!!\n");
	 goto error;
      }
      totag.s=ttag;
      calc_crc_suffix(c->uas.request,seas_tag_suffix);
      LM_DBG("seas_tags = %.*s\n",TOTAG_VALUE_LEN,seas_tags);
      memcpy(totag.s,seas_tags,TOTAG_VALUE_LEN);
      totag.len=TOTAG_VALUE_LEN;*/
   }
   LM_DBG("Using totag=[%.*s]\n",totag.len,totag.s);
   if(my_msg->content_length)
      contentlength=(unsigned int)(long)my_msg->content_length->parsed;
   if(0>(i=recordroute_diff(c->uas.request,my_msg))){/*not likely..*/
      LM_DBG("Seems that request had more RecordRoutes than response...\n");
      /* This prevents host->proxy->host from working. TODO review recordroute_diff code.
      goto error; */
   }else
      LM_DBG("Recordroute Diff = %d\n",i);

   if(0>(i=extract_allowed_headers(my_msg,0,i,HDR_VIA_F|HDR_TO_F|HDR_FROM_F|HDR_CSEQ_F|HDR_CALLID_F|HDR_CONTENTLENGTH_F,headers,MAX_HEADER))){
      LM_ERR("ac_reply() filtering headers !\n");
      goto error;
   }
   headers[i]=0;
   new_header.s=headers;
   new_header.len=i;

   /* If it is INVITE and response is success (>=200 && <300), we mark it as local so that
    * SER does NOT retransmit the final response (by default, SER retransmit local UAS final
    * responses...*/
   if(is_invite(c) && my_msg->first_line.u.reply.statuscode>=200 && my_msg->first_line.u.reply.statuscode<300){
      c->flags |= T_IS_LOCAL_FLAG;
      if(!(the_param=shm_malloc(sizeof(struct as_uac_param)))){
         LM_ERR("no more share memory\n");
         goto error;
      }
      the_param->processor_id=processor_id;
      the_param->who=my_as;
      the_param->destroy_cb_set=0;
      if (seas_f.tmb.register_tmcb( 0, c, TMCB_E2EACK_IN,uas_e2e_ack_cb, the_param,&param_free)<=0) {
         LM_ERR("cannot register additional callbacks\n");
         goto error;
      }
   }
   /*WARNING casting unsigned int to int*/
   body.len=contentlength;
   body.s=get_body(my_msg);

   LM_DBG("Trying to construct a SipReply with: ReasonPhrase:[%.*s] body:[%.*s] headers:[%.*s] totag:[%.*s]\n",\
	 my_msg->first_line.u.reply.reason.len,my_msg->first_line.u.reply.reason.s,\
	 body.len,body.s,new_header.len,new_header.s,totag.len,totag.s);
   /* t_reply_with_body un-ref-counts the transaction, so dont use it anymore*/
   if(seas_f.tmb.t_reply_with_body(c,my_msg->first_line.u.reply.statuscode,&(my_msg->first_line.u.reply.reason),&body,&new_header,&totag)<0){
      LM_ERR("Failed to t_reply\n");
      goto error;
   }
   retval=0;
   goto exit;
error:
   retval = -1;
   if(c)
      seas_f.tmb.unref_cell(c);
   if(the_param)
      shm_free(the_param);
exit:
   if(ttag)
      pkg_free(ttag);
   if(my_msg){
      free_sip_msg_lite(my_msg);
      pkg_free(my_msg);
   }
   return retval;
}
Ejemplo n.º 29
0
static int ki_imc_manager(struct sip_msg* msg)
{
	imc_cmd_t cmd;
	str body;
	struct sip_uri from_uri, *pto_uri=NULL, *pfrom_uri=NULL;
	struct to_body *pfrom;
	int ret = -1;

	body.s = get_body( msg );
	if (body.s==0)
	{
		LM_ERR("cannot extract body from msg\n");
		goto error;
	}

	/* lungimea corpului mesajului */
	if (!msg->content_length)
	{
		LM_ERR("no Content-Length\n");
		goto error;
	}
	body.len = get_content_length( msg );

	if(body.len <= 0)
	{
		LM_DBG("empty body!\n");
		goto error;
	}

	if(parse_sip_msg_uri(msg)<0)
	{
		LM_ERR("failed to parse r-uri\n");
		goto error;
	}

	pto_uri=&msg->parsed_uri;

	if(parse_from_header(msg)<0)
	{
		LM_ERR("failed to parse  From header\n");
		goto error;
	}
	pfrom = (struct to_body*)msg->from->parsed;
	if(parse_uri(pfrom->uri.s, pfrom->uri.len, &from_uri)<0){
		LM_ERR("failed to parse From URI\n");
		goto error;
	}
	pfrom_uri=&from_uri;

	if(body.s[0]== imc_cmd_start_char)
	{
		LM_DBG("found command\n");
		if(imc_parse_cmd(body.s, body.len, &cmd)<0)
		{
			LM_ERR("failed to parse imc cmd!\n");
			ret = -20;
			goto error;
		}

		switch(cmd.type)
		{
		case IMC_CMDID_CREATE:
			if(imc_handle_create(msg, &cmd, pfrom_uri, pto_uri)<0)
			{
				LM_ERR("failed to handle 'create'\n");
				ret = -30;
				goto error;
			}
		break;
		case IMC_CMDID_JOIN:
			if(imc_handle_join(msg, &cmd, pfrom_uri, pto_uri)<0)
			{
				LM_ERR("failed to handle 'join'\n");
				ret = -40;
				goto error;
			}
		break;
		case IMC_CMDID_INVITE:
			if(imc_handle_invite(msg, &cmd, pfrom_uri, pto_uri)<0)
			{
				LM_ERR("failed to handle 'invite'\n");
				ret = -50;
				goto error;
			}
		break;
		case IMC_CMDID_ACCEPT:
			if(imc_handle_accept(msg, &cmd, pfrom_uri, pto_uri)<0)
			{
				LM_ERR("failed to handle 'accept'\n");
				ret = -60;
				goto error;
			}
		break;
		case IMC_CMDID_DENY:
			if(imc_handle_deny(msg, &cmd, pfrom_uri, pto_uri)<0)
			{
				LM_ERR("failed to handle 'deny'\n");
				ret = -70;
				goto error;
			}
		break;
		case IMC_CMDID_REMOVE:
			if(imc_handle_remove(msg, &cmd, pfrom_uri, pto_uri)<0)
			{
				LM_ERR("failed to handle 'remove'\n");
				ret = -80;
				goto error;
			}
		break;
		case IMC_CMDID_EXIT:
			if(imc_handle_exit(msg, &cmd, pfrom_uri, pto_uri)<0)
			{
				LM_ERR("failed to handle 'exit'\n");
				ret = -90;
				goto error;
			}
		break;
		case IMC_CMDID_LIST:
			if(imc_handle_list(msg, &cmd, pfrom_uri, pto_uri)<0)
			{
				LM_ERR("failed to handle 'list'\n");
				ret = -100;
				goto error;
			}
		break;
		case IMC_CMDID_DESTROY:
			if(imc_handle_destroy(msg, &cmd, pfrom_uri, pto_uri)<0)
			{
				LM_ERR("failed to handle 'destroy'\n");
				ret = -110;
				goto error;
			}
		break;
		case IMC_CMDID_HELP:
			if(imc_handle_help(msg, &cmd, &pfrom->uri,
			(msg->new_uri.s)?&msg->new_uri:&msg->first_line.u.request.uri)<0)
			{
				LM_ERR("failed to handle 'help'\n");
				ret = -120;
				goto error;
			}
		break;
		default:
			if(imc_handle_unknown(msg, &cmd, &pfrom->uri,
			(msg->new_uri.s)?&msg->new_uri:&msg->first_line.u.request.uri)<0)
			{
				LM_ERR("failed to handle 'unknown'\n");
				ret = -130;
				goto error;
			}
		}

		goto done;
	}

	if(imc_handle_message(msg, &body, pfrom_uri, pto_uri)<0)
	{
		LM_ERR("failed to handle 'message'\n");
		ret = -200;
		goto error;
	}

done:
	return 1;

error:
	return ret;
}
Ejemplo n.º 30
0
/*Actions are composed as follows:
 * (the action length and type as always= 5 bytes)
 * 4:uac_id
 *
 * int request(str* method, str* req_uri, str* to, str* from, str* headers, str* body, transaction_cb c, void* cp)
 * TODO performance speedup: instead of using
 * dynamically allocated memory for headers,body,totag,reason and my_msg
 * use static buffers.
 *
 */
int ac_uac_req(as_p the_as,unsigned char processor_id,unsigned int flags,char *action,int len)
{
   unsigned int cseq;
   char err_buf[MAX_REASON_LEN];
   struct sip_msg *my_msg;
   struct to_body *fb,*tb;
   struct cseq_body *cseqb;
   struct as_uac_param *the_param;
   dlg_t *my_dlg;
   int k,retval,uac_id,sip_error,ret,err_ret;
   long clen;
   str headers,body,fake_uri;
   uac_req_t uac_r;

   headers.s=body.s=fake_uri.s=NULL;
   my_dlg=NULL;
   my_msg=NULL;
   the_param=NULL;
   k=clen=0;

   net2hostL(uac_id,action,k);

   if(!(headers.s=pkg_malloc(MAX_HEADER))){
      LM_ERR("Out of Memory!!");
      goto error;
   }
   headers.len=0;
   LM_DBG("Action UAC Message: uac_id:%d processor_id=%d\n",uac_id,processor_id);
   if (!(my_msg = parse_ac_msg(HDR_EOH_F,action+k,len-k))) {
      LM_ERR("out of memory!\n");
      goto error;
   }
   if(my_msg->first_line.type==SIP_REPLY){
      LM_ERR("trying to create a UAC with a SIP response!!\n");
      goto error;
   }
   if(parse_headers(my_msg,HDR_EOH_F,0)==-1){
      LM_ERR("ERROR:seas:ac_uac_req:parsing headers\n");
      goto error;
   }
   if(parse_from_header(my_msg)<0){
      LM_ERR("parsing from header ! \n");
      goto error;
   }
   if(check_transaction_quadruple(my_msg)==0){
      as_action_fail_resp(uac_id,SE_UAC,"Headers missing (to,from,call-id,cseq)?",0);
      LM_ERR("Headers missing (to,from,call-id,cseq)?");
      goto error;
   }
   if(!(get_from(my_msg)) || !(get_from(my_msg)->tag_value.s) || 
	 !(get_from(my_msg)->tag_value.len)){
      as_action_fail_resp(uac_id,SE_UAC,"From tag missing",0);
      LM_ERR("From tag missing");
      goto error;
   }
   fb=my_msg->from->parsed;
   tb=my_msg->to->parsed;
   cseqb=my_msg->cseq->parsed;
   if(0!=(str2int(&cseqb->number,&cseq))){
      LM_DBG("unable to parse CSeq\n");
      goto error;
   }
   if(my_msg->first_line.u.request.method_value != METHOD_ACK &&
	 my_msg->first_line.u.request.method_value != METHOD_CANCEL) {
      /** we trick req_within */
      cseq--;
   }
   if(seas_f.tmb.new_dlg_uac(&(my_msg->callid->body),&(fb->tag_value),cseq,\
	    &(fb->uri),&(tb->uri),&my_dlg) < 0) {
      as_action_fail_resp(uac_id,SE_UAC,"Error creating new dialog",0);
      LM_ERR("Error while creating new dialog\n");
      goto error;
   }
   if(seas_f.tmb.dlg_add_extra(my_dlg,&(fb->display),&(tb->display)) < 0 ) {
      as_action_fail_resp(uac_id,SE_UAC,
         "Error adding the display names to the new dialog",0);
      LM_ERR("failed to add display names to the new dialog\n");
      goto error;
   }

   if(tb->tag_value.s && tb->tag_value.len)
      shm_str_dup(&my_dlg->id.rem_tag,&tb->tag_value);
   /**Awful hack: to be able to set our own CSeq, from_tag and call-ID we have
    * to use req_within instead of req_outside (it sets it's own CSeq,Call-ID
    * and ftag), so we have to simulate that the dialog is already in completed
    * state so...
    */
   server_signature=0;
   my_dlg->state = DLG_CONFIRMED;
   if(0>(headers.len=extract_allowed_headers(my_msg,1,-1,HDR_CONTENTLENGTH_F|HDR_ROUTE_F|HDR_TO_F|HDR_FROM_F|HDR_CALLID_F|HDR_CSEQ_F,headers.s,MAX_HEADER))) {
      LM_ERR("Unable to extract allowed headers!!\n");
      goto error;
   }
   headers.s[headers.len]=0;
   /*let's get the body*/
   if(my_msg->content_length)
      clen=(long)get_content_length(my_msg);
   if(clen!=0){
      if(!(body.s=pkg_malloc(clen))){
	 LM_ERR("Out of Memory!");
	 goto error;
      }
      memcpy(body.s,get_body(my_msg),clen);
      body.len=clen;
      body.s[clen]=0;
      LM_DBG("Trying to construct a Sip Request with: body:%d[%.*s] headers:%d[%.*s]\n",\
	    body.len,body.len,body.s,headers.len,headers.len,headers.s);
      /*t_reply_with_body un-ref-counts the transaction, so dont use it anymore*/
   }else{
      body.s=NULL;
      body.len=0;
   }
   /*Now... create the UAC !!
    * it would be great to know the hash_index and the label that have been assigned
    * to our newly created cell, but t_uac does not leave any way for us to know...
    * only that when that transaction transitions its state (ie. a response is received,
    * a timeout is reached, etc...) the callback will be called with the given parameter.
    *
    * So the only way we have to know who we are, is passing as a parameter a structure with
    * 2 pointers: one to the app_server and the other, the identifier of the UAC (uac_id).
    *
    */
   if(!(the_param=shm_malloc(sizeof(struct as_uac_param)))){
      LM_ERR("out of shared memory\n");
      goto error;
   }
   the_param->who=my_as;
   the_param->uac_id=uac_id;
   the_param->processor_id=processor_id;
   the_param->destroy_cb_set=0;

   shm_str_dup(&my_dlg->rem_target,&my_msg->first_line.u.request.uri);

   if (my_msg->route) {
      if (parse_rr(my_msg->route) < 0) {
	 LM_ERR( "Error while parsing Route body\n");
	 goto error;
      }
      /* TODO route_set should be a shm copy of my_msg->route->parsed */
      my_dlg->route_set=(rr_t*)my_msg->route->parsed;
      /** this SHOULD be:
       shm_duplicate_rr(&my_dlg->route_set,my_msg->route->parsed);
       * but it will last more...
       */
   }
   calculate_hooks(my_dlg);
   if(flags & SPIRAL_FLAG){
      memcpy(headers.s+headers.len,SPIRAL_HDR CRLF,SPIRAL_HDR_LEN + CRLF_LEN);
      headers.len+=SPIRAL_HDR_LEN+CRLF_LEN;
      headers.s[headers.len]=0;
      fake_uri.s=pkg_malloc(200);
      fake_uri.len=print_local_uri(the_as,processor_id,fake_uri.s,200);

      if(fake_uri.len<0){
	 LM_ERR("printing local uri\n");
	 goto error;
      }
      my_dlg->hooks.next_hop=&fake_uri;
   }
   /* Kamailio and OpenSIPs seem to have diverged quite a bit on flags and events
      notified to UACs. Let's see if kamailio gets it right by now, if not
      this is a TODO: check PASS_PROVISIONAL
      my_dlg->T_flags=T_NO_AUTO_ACK|T_PASS_PROVISIONAL_FLAG ;
      this is the same as (TMCB_DONT_ACK|TMCB_LOCAL_RESPONSE_OUT) in Kamailio
   */

   set_uac_req(&uac_r, &(my_msg->first_line.u.request.method), &headers,
		   &body, my_dlg,TMCB_DONT_ACK|TMCB_LOCAL_RESPONSE_OUT, uac_cb,
		   (void*)the_param);

   ret=seas_f.tmb.t_request_within(&uac_r);

   /** now undo all the fakes we have put in my_dlg*/
   /*because my_dlg->route_set should be shm but we fake it (its pkg_mem)*/
   my_dlg->route_set=(rr_t *)0;
   if (ret < 0) {
      err_ret = err2reason_phrase(ret,&sip_error,err_buf, sizeof(err_buf), "SEAS/UAC");
      LM_ERR("failed to send the [%.*s] request\n",uac_r.method->len,uac_r.method->s);
      LM_ERR("Error on request_within %s\n",err_buf );
      if(err_ret > 0) {
	 as_action_fail_resp(uac_id,ret,err_buf,0);
      }else{
	 as_action_fail_resp(uac_id,E_UNSPEC,"500 SEAS/UAC error",0);
      }
      goto error;
   }
   retval=0;
   goto exit;
error:
   retval = -1;
   if(the_param)
      shm_free(the_param);
exit:
   seas_f.tmb.free_dlg(my_dlg);
   if(headers.s)
      pkg_free(headers.s);
   if(body.s)
      pkg_free(body.s);
   if(fake_uri.s)
      pkg_free(fake_uri.s);
   if(my_msg){
      if(my_msg->headers)
	 free_hdr_field_lst(my_msg->headers);
      pkg_free(my_msg);
   }
   return retval;
}