Ejemplo n.º 1
0
void test_create_file_at()
{
  char *file = alloc_filename("file");
  char *hardlink = alloc_filename("hardlink");
  char *hardlink2 = alloc_filename("hardlink2");
  int dir_fd = get_dir_fd(".");
  struct stat st;
  int fd = openat(dir_fd, file, O_CREAT | O_WRONLY | O_EXCL, 0777);
  t_check(fd >= 0);
  t_check_zero(fstat(fd, &st));
  t_check_zero(close(fd));

  t_check_zero(fstatat(dir_fd, file, &st, 0));
  t_check_zero(faccessat(dir_fd, file, R_OK | W_OK, 0));
  t_check_zero(fchmodat(dir_fd, file, 0777, 0));
  t_check_zero(fchownat(dir_fd, file, -1, -1, 0));
  struct timeval times[2] = { { 123, 321 }, { 456, 654 } };
  t_check_zero(futimesat(dir_fd, file, times));

  t_check_zero(linkat(dir_fd, file, dir_fd, hardlink, 0));
  t_check_zero(renameat(dir_fd, hardlink, dir_fd, hardlink2));
  t_check_zero(unlinkat(dir_fd, hardlink2, 0));
  t_check_zero(unlinkat(dir_fd, file, 0));
  close(dir_fd);
  free(file);
  free(hardlink);
  free(hardlink2);
}
Ejemplo n.º 2
0
static int t_flush_flags(struct sip_msg* msg, char *dir, char *foo)
{
	struct cell *t;

	/* first get the transaction */
	if (t_check( msg , 0 )==-1) return -1;
	if ( (t=get_t())==0) {
		LOG(L_ERR, "ERROR: t_flush_flags: cannot flush flags for a message "
			"which has no T-state established\n");
		return -1;
	}

	/* do the flush */
	switch ((long)dir) {
		case  1:
			t->uas.request->flags = msg->flags;
			break;
		case  2:
			msg->flags = t->uas.request->flags;
			break;
		default:
			LOG(L_ERR,"ERROR:t_flush_flags: unknown direction %ld\n",
					(long)dir);
			return -1;
	}
	return 1;
}
Ejemplo n.º 3
0
inline static int w_t_reply(struct sip_msg* msg, char* str, char* str2)
{
	struct cell *t;

	if (msg->REQ_METHOD==METHOD_ACK) {
		LOG(L_WARN, "WARNING: t_reply: ACKs are not replied\n");
		return -1;
	}
	if (t_check( msg , 0 )==-1) return -1;
	t=get_t();
	if (!t) {
		LOG(L_ERR, "ERROR: t_reply: cannot send a t_reply to a message "
			"for which no T-state has been established\n");
		return -1;
	}
	/* if called from reply_route, make sure that unsafe version
	 * is called; we are already in a mutex and another mutex in
	 * the safe version would lead to a deadlock
	 */
	if (rmode==MODE_ONFAILURE) { 
		DBG("DEBUG: t_reply_unsafe called from w_t_reply\n");
		return t_reply_unsafe(t, msg, (unsigned int)(long) str, str2);
	} else if (rmode==MODE_REQUEST) {
		return t_reply( t, msg, (unsigned int)(long) str, str2);
	} else {
		LOG(L_CRIT, "BUG: w_t_reply entered in unsupported mode\n");
		return -1;
	}
}
Ejemplo n.º 4
0
void test_create_file()
{
  char *file = alloc_filename("file");
  char *hardlink = alloc_filename("hardlink");
  char *hardlink2 = alloc_filename("hardlink2");
  struct stat st;
  int fd = open(file, O_CREAT | O_WRONLY | O_EXCL, 0666);
  t_check(fd >= 0);
  t_check_zero(fstat(fd, &st));
  t_check_zero(close(fd));

  t_check_zero(stat(file, &st));
  t_check_zero(access(file, R_OK | W_OK));
  t_check_zero(chmod(file, 0777));
  t_check_zero(chown(file, -1, -1));
  struct timeval times[2] = { { 123, 321 }, { 456, 654 } };
  t_check_zero(utimes(file, times));

  t_check_zero(link(file, hardlink));
  t_check_zero(rename(hardlink, hardlink2));
  t_check_zero(unlink(hardlink2));
  t_check_zero(unlink(file));
  free(file);
  free(hardlink);
  free(hardlink2);
}
Ejemplo n.º 5
0
Archivo: tm.c Proyecto: Deni90/opensips
static int pv_get_tm_ruri(struct sip_msg *msg, pv_param_t *param,
		pv_value_t *res)
{
	struct cell *t;

	if(msg==NULL || res==NULL)
		return -1;

	/* first get the transaction */
	if (t_check( msg , 0 )==-1) return -1;
	if ( (t=get_t())==0) {
		/* no T */
		if (msg!=NULL&&msg!=FAKED_REPLY && msg->first_line.type==SIP_REQUEST){
			res->rs = *GET_RURI(msg);
			res->flags = PV_VAL_STR;
			return 0;
		}
		return pv_get_null(msg, param,res);
	}

	/* return the RURI for the current branch */
	if (_tm_branch_index>=t->nr_of_outgoings) {
		LM_ERR("BUG: _tm_branch_index greater than nr_of_outgoings\n");
		return -1;
	}

	res->rs = t->uac[_tm_branch_index].uri;

	res->flags = PV_VAL_STR;

	return 0;
}
Ejemplo n.º 6
0
inline static int w_t_reply(struct sip_msg* msg, char* str, char* str2)
{
	struct cell *t;

	if (msg->REQ_METHOD==METHOD_ACK) {
		LOG(L_WARN, "WARNING: t_reply: ACKs are not replied\n");
		return -1;
	}
	if (t_check( msg , 0 )==-1) return -1;
	t=get_t();
	if (!t) {
		LOG(L_ERR, "ERROR: t_reply: cannot send a t_reply to a message "
			"for which no T-state has been established\n");
		return -1;
	}
	/* if called from reply_route, make sure that unsafe version
	 * is called; we are already in a mutex and another mutex in
	 * the safe version would lead to a deadlock
	 */
	switch (route_type) {
		case FAILURE_ROUTE:
			DBG("DEBUG: t_reply_unsafe called from w_t_reply\n");
			return t_reply_unsafe(t, msg, (unsigned int)(long) str, str2);
		case REQUEST_ROUTE:
			return t_reply( t, msg, (unsigned int)(long) str, str2);
		default:
			LOG(L_CRIT, "BUG:tm:w_t_reply: unsupported route_type (%d)\n",
				route_type);
			return -1;
	}
}
Ejemplo n.º 7
0
inline static int t_local_replied(struct sip_msg* msg, char *all, char *bar)
{
	struct cell *t;
	int all_rpls;
	int i;

	if (t_check( msg , 0 )!=1) {
		LOG(L_ERR, "ERROR:t_local_replied: no transaction was set up\n");
		return -1;
	}
	t = get_t();

	all_rpls = (int)(long)all;

	/* is last reply local ? */
	if (t->relaied_reply_branch!=-2)
		return -1;
	/* were all replies local or none  */
	if (all_rpls) {
		for( i=t->first_branch ; i<t->nr_of_outgoings ; i++ ) {
			if (t->uac[i].flags&T_UAC_HAS_RECV_REPLY)
				return -1;
		}
	}

	return 1;
}
Ejemplo n.º 8
0
inline static int w_t_release(struct sip_msg* msg, char* str, char* str2)
{
	struct cell *t;
	if (t_check( msg  , 0  )==-1) return -1;
	t=get_t();
	if ( t && t!=T_UNDEFINED ) 
		return t_release_transaction( t );
	return 1;
}
Ejemplo n.º 9
0
void test_open_dir_fd()
{
  int fd = open(".", O_RDONLY);
  t_check(fd >= 0);
  struct stat st;
  t_check_zero(fstat(fd, &st));
  t_check_zero(fchdir(fd));
  t_check_zero(close(fd));
}
Ejemplo n.º 10
0
/* register a callback function 'f' for 'types' mask of events;
 * will be called back whenever one of the events occurs in transaction module
 * (global or per transaction, depending of event type)
 * It _must_ be always called either with the REPLY_LOCK held, or before the
 *  branches are created.
 *  Special cases: TMCB_REQUEST_IN & TMCB_LOCAL_REQUEST_IN - must be called 
 *                 from mod_init (before forking!).
*/
int register_tmcb( struct sip_msg* p_msg, struct cell *t, int types,
											transaction_cb f, void *param )
{
	//struct cell* t;
	struct tmcb_head_list *cb_list;

	/* are the callback types valid?... */
	if ( types<0 || types>TMCB_MAX ) {
		LOG(L_CRIT, "BUG:tm:register_tmcb: invalid callback types: mask=%d\n",
			types);
		return E_BUG;
	}
	/* we don't register null functions */
	if (f==0) {
		LOG(L_CRIT, "BUG:tm:register_tmcb: null callback function\n");
		return E_BUG;
	}

	if (types&TMCB_REQUEST_IN) {
		if (types!=TMCB_REQUEST_IN) {
			LOG(L_CRIT, "BUG:tm:register_tmcb: callback type TMCB_REQUEST_IN "
				"can't be register along with types\n");
			return E_BUG;
		}
		cb_list = req_in_tmcb_hl;
	}else if (types & TMCB_LOCAL_REQUEST_IN) {
		if (types!=TMCB_LOCAL_REQUEST_IN) {
			LOG(L_CRIT, "BUG:tm:register_tmcb: callback type"
					" TMCB_LOCAL_REQUEST_IN can't be register along with"
					" other types\n");
			return E_BUG;
		}
		cb_list = local_req_in_tmcb_hl;
	} else {
		if (!t) {
			if (!p_msg) {
				LOG(L_CRIT,"BUG:tm:register_tmcb: no sip_msg, nor transaction"
					" given\n");
				return E_BUG;
			}
			/* look for the transaction */
			if ( t_check(p_msg,0)!=1 ){
				LOG(L_CRIT,"BUG:tm:register_tmcb: no transaction found\n");
				return E_BUG;
			}
			if ( (t=get_t())==0 ) {
				LOG(L_CRIT,"BUG:tm:register_tmcb: transaction found "
					"is NULL\n");
				return E_BUG;
			}
		}
		cb_list = &(t->tmcb_hl);
	}

	return insert_tmcb( cb_list, types, f, param );
}
Ejemplo n.º 11
0
void test_readdir()
{
  DIR *dir = opendir(".");
  t_check(dir != NULL);
  while(1) {
    struct dirent *ent = readdir(dir);
    if(ent == NULL)
      break;
  }
  t_check_zero(closedir(dir));
}
Ejemplo n.º 12
0
inline static int select_tm_get_cell(struct sip_msg* msg, int *branch, struct cell **t) {

	/* make sure we know the associated transaction ... */
	if (t_check( msg  , branch )==-1)  /* it's not necessary whan calling from script because already done */ 
		return -1;

	/*... if there is none, tell the core router to fwd statelessly */
	*t = get_t();
	if ( (*t==0)||(*t==T_UNDEFINED)) return -1;

	return 0;
}	
Ejemplo n.º 13
0
/**************************** wrapper functions ***************************/
static int t_check_status(struct sip_msg* msg, char *regexp, char *foo)
{
	regmatch_t pmatch;
	struct cell *t;
	char *status;
	char backup;
	int lowest_status;
	int n;

	/* first get the transaction */
	if (t_check( msg , 0 )==-1) return -1;
	if ( (t=get_t())==0) {
		LOG(L_ERR, "ERROR: t_check_status: cannot check status for a reply "
			"which has no T-state established\n");
		return -1;
	}
	backup = 0;

	switch (route_type) {
		case REQUEST_ROUTE:
			/* use the status of the last sent reply */
			status = int2str( t->uas.status, 0);
			break;
		case ONREPLY_ROUTE:
			/* use the status of the current reply */
			status = msg->first_line.u.reply.status.s;
			backup = status[msg->first_line.u.reply.status.len];
			status[msg->first_line.u.reply.status.len] = 0;
			break;
		case FAILURE_ROUTE:
			/* use the status of the winning reply */
			if (t_pick_branch( -1, 0, t, &lowest_status)<0 ) {
				LOG(L_CRIT,"BUG:t_check_status: t_pick_branch failed to get "
					" a final response in MODE_ONFAILURE\n");
				return -1;
			}
			status = int2str( lowest_status , 0);
			break;
		default:
			LOG(L_ERR,"ERROR:t_check_status: unsupported route_type %d\n",
					route_type);
			return -1;
	}

	DBG("DEBUG:t_check_status: checked status is <%s>\n",status);
	/* do the checking */
	n = regexec((regex_t*)regexp, status, 1, &pmatch, 0);

	if (backup) status[msg->first_line.u.reply.status.len] = backup;
	if (n!=0) return -1;
	return 1;
}
Ejemplo n.º 14
0
static int t_was_cancelled(struct sip_msg* msg, char *foo, char *bar)
{
	struct cell *t;

	/* first get the transaction */
	if (t_check( msg , 0 )==-1) return -1;
	if ( (t=get_t())==0) {
		LOG(L_ERR, "ERROR:tm:t_was_cancelled: cannot check cancel flag for "
			"a reply without a transaction\n");
		return -1;
	}
	return (t->flags&T_WAS_CANCELLED_FLAG)?1:-1;
}
Ejemplo n.º 15
0
Archivo: tm.c Proyecto: Deni90/opensips
static int pv_get_tm_reply_code(struct sip_msg *msg, pv_param_t *param,
		pv_value_t *res)
{
	struct cell *t;
	int code;
	int branch;

	if(msg==NULL || res==NULL)
		return -1;

	/* first get the transaction */
	if (t_check( msg , 0 )==-1) return -1;
	if ( (t=get_t())==0) {
		/* no T */
		code = 0;
	} else {
		switch (route_type) {
			case REQUEST_ROUTE:
				/* use the status of the last sent reply */
				code = t->uas.status;
				break;
			case ONREPLY_ROUTE:
				/* use the status of the current reply */
				code = msg->first_line.u.reply.statuscode;
				break;
			case FAILURE_ROUTE:
				/* use the status of the winning reply */
				if ( (branch=t_get_picked_branch())<0 ) {
					LM_CRIT("no picked branch (%d) for a final response"
							" in MODE_ONFAILURE\n", branch);
					code = 0;
				} else {
					code = t->uac[branch].last_received;
				}
				break;
			default:
				LM_ERR("unsupported route_type %d\n", route_type);
				code = 0;
		}
	}

	LM_DBG("reply code is <%d>\n",code);

	res->rs.s = int2str( code, &res->rs.len);

	res->ri = code;
	res->flags = PV_VAL_STR|PV_VAL_INT|PV_TYPE_INT;
	return 0;
}
Ejemplo n.º 16
0
int t_is_local(struct sip_msg* p_msg)
{
    struct cell* t;
    if(t_check(p_msg,0) != 1){
	LOG(L_ERR,"ERROR: t_is_local: no transaction found\n");
	return -1;
    }
    t = get_t();
    if(!t){
	LOG(L_ERR,"ERROR: t_is_local: transaction found is NULL\n");
	return -1;
    }
    
    return is_local(t);
}
Ejemplo n.º 17
0
inline static int w_t_reply(struct sip_msg* msg, char* p1, char* p2)
{
	struct cell *t;
	int code, ret = -1;
	str reason;
	char* r;

	if (msg->REQ_METHOD==METHOD_ACK) {
		LOG(L_WARN, "WARNING: t_reply: ACKs are not replied\n");
		return -1;
	}
	if (t_check( msg , 0 )==-1) return -1;
	t=get_t();
	if (!t) {
		LOG(L_ERR, "ERROR: t_reply: cannot send a t_reply to a message "
			"for which no T-state has been established\n");
		return -1;
	}

	if (get_int_fparam(&code, msg, (fparam_t*)p1) < 0) {
	    code = default_code;
	}
	
	if (get_str_fparam(&reason, msg, (fparam_t*)p2) < 0) {
	    reason = default_reason;
	}
	
	r = as_asciiz(&reason);
	if (r == NULL) r = default_reason.s;
	
	/* if called from reply_route, make sure that unsafe version
	 * is called; we are already in a mutex and another mutex in
	 * the safe version would lead to a deadlock
	 */
	 
	if (rmode==MODE_ONFAILURE) {
		DBG("DEBUG: t_reply_unsafe called from w_t_reply\n");
		ret = t_reply_unsafe(t, msg, code, r);
	} else if (rmode==MODE_REQUEST) {
		ret = t_reply( t, msg, code, r);
	} else {
		LOG(L_CRIT, "BUG: w_t_reply entered in unsupported mode\n");
		ret = -1;
	}

	if (r) pkg_free(r);
	return ret;
}
Ejemplo n.º 18
0
void test_bind()
{
  char *socket_filename = alloc_filename("socket");
  int fd;
  struct sockaddr_un addr;

  fd = socket(PF_UNIX, SOCK_STREAM, 0);
  t_check(fd >= 0);
  addr.sun_family = AF_UNIX;
  strcpy(addr.sun_path, socket_filename);
  t_check_zero(bind(fd, (struct sockaddr *) &addr,
                    sizeof(struct sockaddr_un)));
  t_check_zero(close(fd));
  t_check_zero(unlink(socket_filename));
  free(socket_filename);
}
Ejemplo n.º 19
0
/* script function, returns: 1 if the transaction was canceled, -1 if not */
int t_is_canceled(struct sip_msg* msg, char* foo, char* bar)
{
	struct cell *t;
	int ret;
	
	
	if (t_check( msg , 0 )==-1) return -1;
	t=get_t();
	if ((t==0) || (t==T_UNDEFINED)){
		LOG(L_ERR, "ERROR: t_is_canceled: cannot check a message "
			"for which no T-state has been established\n");
		ret=-1;
	}else{
		ret=(t->flags & T_CANCELED)?1:-1;
	}
	return ret;
}
Ejemplo n.º 20
0
inline static int w_t_retransmit_reply( struct sip_msg* p_msg, char* foo, char* bar)
{
	struct cell *t;


	if (t_check( p_msg  , 0 )==-1)
		return 1;
	t=get_t();
	if (t) {
		if (p_msg->REQ_METHOD==METHOD_ACK) {
			LOG(L_WARN, "WARNING: : ACKs transmit_replies not replied\n");
			return -1;
		}
		return t_retransmit_reply( t );
	} else
		return -1;
}
Ejemplo n.º 21
0
void test_create_symlink()
{
  char *symlink_filename = alloc_filename("symlink");
  const char *dest_path = "dest_path";
  t_check_zero(symlink(dest_path, symlink_filename));

  char buf[100];
  int got;
  got = readlink(symlink_filename, buf, sizeof(buf));
  t_check(got >= 0);
  assert(got == strlen(dest_path));
  buf[got] = 0;
  assert(strcmp(buf, dest_path) == 0);

  t_check_zero(unlink(symlink_filename));
  free(symlink_filename);
}
Ejemplo n.º 22
0
int t_get_trans_ident(struct sip_msg* p_msg, unsigned int* hash_index, unsigned int* label)
{
    struct cell* t;
    if(t_check(p_msg,0) != 1){
	LOG(L_ERR,"ERROR: t_get_trans_ident: no transaction found\n");
	return -1;
    }
    t = get_t();
    if(!t){
	LOG(L_ERR,"ERROR: t_get_trans_ident: transaction found is NULL\n");
	return -1;
    }
    
    *hash_index = t->hash_index;
    *label = t->label;

    return 1;
}
Ejemplo n.º 23
0
/* script function, returns: 1 if any of the branches received at leat one
 * reply, -1 if not */
int t_any_replied(struct sip_msg* msg, char* foo, char* bar)
{
	struct cell *t;
	int r;
	
	if (t_check( msg , 0 )==-1) return -1;
	t=get_t();
	if ((t==0) || (t==T_UNDEFINED)){
		LOG(L_ERR, "ERROR: t_any_replied: cannot check a message "
			"for which no T-state has been established\n");
		return -1;
	}else{
		for (r=0; r<t->nr_of_outgoings; r++){
			if (t->uac[r].request.flags & F_RB_REPLIED)
				return 1;
		}
	}
	return -1;
}
Ejemplo n.º 24
0
inline static int _w_t_forward_nonack(struct sip_msg* msg, struct proxy_l* proxy,
	int proto)
{
	struct cell *t;
	if (t_check( msg , 0 )==-1) {
		LOG(L_ERR, "ERROR: forward_nonack: "
				"can't forward when no transaction was set up\n");
		return -1;
	}
	t=get_t();
	if ( t && t!=T_UNDEFINED ) {
		if (msg->REQ_METHOD==METHOD_ACK) {
			LOG(L_WARN,"WARNING: you don't really want to fwd hbh ACK\n");
			return -1;
		}
		return t_forward_nonack(t, msg, proxy, proto );
	} else {
		DBG("DEBUG: forward_nonack: no transaction found\n");
		return -1;
	}
}
Ejemplo n.º 25
0
/*  This function is called whenever a reply for our module is received; 
  * we need to register  this function on module initialization;
  *  Returns :   0 - core router stops
  *              1 - core router relay statelessly
  */
int reply_received( struct sip_msg  *p_msg )
{
	int msg_status;
	int last_uac_status;
	int branch;
	int reply_status;
	utime_t timer;
	/* has the transaction completed now and we need to clean-up? */
	branch_bm_t cancel_bitmap;
	struct ua_client *uac;
	struct cell *t;
	struct usr_avp **backup_list;
	unsigned int has_reply_route;

	set_t(T_UNDEFINED);

	/* make sure we know the associated transaction ... */
	if (t_check(p_msg, &branch ) == -1) goto not_found;

	/*... if there is none, tell the core router to fwd statelessly */
	t = get_t();
	if ((t == 0) || (t == T_UNDEFINED)) goto not_found;

	cancel_bitmap=0;
	msg_status=p_msg->REPLY_STATUS;

	uac=&t->uac[branch];
	LM_DBG("org. status uas=%d, uac[%d]=%d local=%d is_invite=%d)\n",
		t->uas.status, branch, uac->last_received, 
		is_local(t), is_invite(t));
	last_uac_status=uac->last_received;
	if_update_stat( tm_enable_stats, tm_rcv_rpls , 1);

	/* it's a cancel which is not e2e ? */
	if ( get_cseq(p_msg)->method_id==METHOD_CANCEL && is_invite(t) ) {
		/* ... then just stop timers */
		reset_timer( &uac->local_cancel.retr_timer);
		if ( msg_status >= 200 ) {
				reset_timer( &uac->local_cancel.fr_timer);
		}
		LM_DBG("reply to local CANCEL processed\n");
		goto done;
	}

	/* *** stop timers *** */
	/* stop retransmission */
	reset_timer(&uac->request.retr_timer);

	/* stop final response timer only if I got a final response */
	if ( msg_status >= 200 ) {
		reset_timer( &uac->request.fr_timer);
	}

	/* acknowledge negative INVITE replies (do it before detailed
	 * on_reply processing, which may take very long, like if it
	 * is attempted to establish a TCP connection to a fail-over dst */
	if (is_invite(t) && ((msg_status >= 300) ||
	(is_local(t) && !no_autoack(t) && msg_status >= 200) )) {
		if (send_ack(p_msg, t, branch)!=0)
			LM_ERR("failed to send ACK (local=%s)\n", is_local(t)?"yes":"no");
	}

	_tm_branch_index = branch;

	/* processing of on_reply block */
	has_reply_route = (t->on_reply) || (t->uac[branch].on_reply);
	if (has_reply_route) {
		if (onreply_avp_mode) {
			/* lock the reply*/
			LOCK_REPLIES( t );
			/* set the as avp_list the one from transaction */
			backup_list = set_avp_list(&t->user_avps);
		} else {
			backup_list = 0;
		}
		/* transfer transaction flag to branch context */
		p_msg->flags = t->uas.request->flags;
		setb0flags(t->uac[branch].br_flags);
		/* run block - first per branch and then global one */
		if ( t->uac[branch].on_reply &&
		(run_top_route(onreply_rlist[t->uac[branch].on_reply].a,p_msg)
		&ACT_FL_DROP) && (msg_status<200) ) {
			if (onreply_avp_mode) {
				UNLOCK_REPLIES( t );
				set_avp_list( backup_list );
			}
			LM_DBG("dropping provisional reply %d\n", msg_status);
			goto done;
		}
		if ( t->on_reply && (run_top_route(onreply_rlist[t->on_reply].a,p_msg)
		&ACT_FL_DROP) && (msg_status<200) ) {
			if (onreply_avp_mode) {
				UNLOCK_REPLIES( t );
				set_avp_list( backup_list );
			}
			LM_DBG("dropping provisional reply %d\n", msg_status);
			goto done;
		}
		/* transfer current message context back to t */
		t->uac[branch].br_flags = getb0flags();
		t->uas.request->flags = p_msg->flags;
		if (onreply_avp_mode)
			/* restore original avp list */
			set_avp_list( backup_list );
	}

	if (!onreply_avp_mode || !has_reply_route)
		/* lock the reply*/
		LOCK_REPLIES( t );

	/* mark that the UAC received replies */
	uac->flags |= T_UAC_HAS_RECV_REPLY;

	/* we fire a cancel on spot if (a) branch is marked "to be canceled" or (b)
	 * the whole transaction was canceled (received cancel) and no cancel sent
	 * yet on this branch; and of course, only if a provisional reply :) */
	if (t->uac[branch].flags&T_UAC_TO_CANCEL_FLAG ||
	((t->flags&T_WAS_CANCELLED_FLAG) && !t->uac[branch].local_cancel.buffer.s)) {
		if ( msg_status < 200 )
			/* reply for an UAC with a pending cancel -> do cancel now */
			cancel_branch(t, branch);
		/* reset flag */
		t->uac[branch].flags &= ~(T_UAC_TO_CANCEL_FLAG);
	}

	if (is_local(t)) {
		reply_status = local_reply(t,p_msg, branch,msg_status,&cancel_bitmap);
		if (reply_status == RPS_COMPLETED) {
			cleanup_uac_timers(t);
			if (is_invite(t)) cancel_uacs(t, cancel_bitmap);
			/* There is no need to call set_final_timer because we know
			 * that the transaction is local */
			put_on_wait(t);
		}
	} else {
		reply_status = relay_reply(t,p_msg,branch,msg_status,&cancel_bitmap);
		/* clean-up the transaction when transaction completed */
		if (reply_status == RPS_COMPLETED) {
			/* no more UAC FR/RETR (if I received a 2xx, there may
			 * be still pending branches ...
			 */
			cleanup_uac_timers(t);
			if (is_invite(t)) cancel_uacs(t, cancel_bitmap);
			/* FR for negative INVITES, WAIT anything else */
			/* set_final_timer(t); */
		}
	}
	
	if (reply_status!=RPS_PROVISIONAL)
		goto done;
	
	/* update FR/RETR timers on provisional replies */
	if (msg_status < 200 && (restart_fr_on_each_reply ||
	((last_uac_status<msg_status) &&
	((msg_status >= 180) || (last_uac_status == 0)))
	) ) { /* provisional now */
		if (is_invite(t)) {
			/* invite: change FR to longer FR_INV, do not
			 * attempt to restart retransmission any more
			 */
			backup_list = set_avp_list(&t->user_avps);
			if (!fr_inv_avp2timer(&timer)) {
				LM_DBG("FR_INV_TIMER = %lld\n", timer);
				set_timer(&uac->request.fr_timer,
					FR_INV_TIMER_LIST, &timer);
			} else {
				set_timer(& uac->request.fr_timer, FR_INV_TIMER_LIST, 0);
			}
			set_avp_list(backup_list);
		} else {
			/* non-invite: restart retransmissions (slow now) */
			uac->request.retr_list = RT_T2;
			set_timer(&uac->request.retr_timer, RT_T2, 0);
		}
	} /* provisional replies */
	
done:
	/* we are done with the transaction, so unref it - the reference
	 * was incremented by t_check() function -bogdan*/
	t_unref(p_msg);
	/* don't try to relay statelessly neither on success
	 * (we forwarded statefully) nor on error; on troubles, 
	 * simply do nothing; that will make the other party to 
	 * retransmit; hopefuly, we'll then be better off 
	 */
	_tm_branch_index = 0;
	return 0;
not_found:
	set_t(T_UNDEFINED);
	return 1;
}
Ejemplo n.º 26
0
/* Suspends the transaction for later use.
 * Save the returned hash_index and label to get
 * back to the SIP request processing, see the readme.
 *
 * Return value:
 * 	0  - success
 * 	<0 - failure
 */
int t_suspend(struct sip_msg *msg,
		unsigned int *hash_index, unsigned int *label)
{
	struct cell	*t;
	int branch;
	int sip_msg_len;

	t = get_t();
	if (!t || t == T_UNDEFINED) {
		LM_ERR("transaction has not been created yet\n");
		return -1;
	}

	if (t->flags & T_CANCELED) {
		/* The transaction has already been canceled */
		LM_DBG("trying to suspend an already canceled transaction\n");
		ser_error = E_CANCELED;
		return 1;
	}
	if (t->uas.status >= 200) {
		LM_DBG("trasaction sent out a final response already - %d\n",
				t->uas.status);
		return -3;
	}

	if (msg->first_line.type != SIP_REPLY) {
		/* send a 100 Trying reply, because the INVITE processing
		will probably take a long time */
		if (msg->REQ_METHOD==METHOD_INVITE && (t->flags&T_AUTO_INV_100)
			&& (t->uas.status < 100)
		) {
			if (!t_reply( t, msg , 100 ,
				cfg_get(tm, tm_cfg, tm_auto_inv_100_r)))
				LM_DBG("suspending request processing - sending 100 reply\n");
		}

		if ((t->nr_of_outgoings==0) && /* if there had already been
			an UAC created, then the lumps were
			saved as well */
			save_msg_lumps(t->uas.request, msg)
		) {
			LM_ERR("failed to save the message lumps\n");
			return -1;
		}
		/* save the message flags */
		t->uas.request->flags = msg->flags;

		/* add a blind UAC to let the fr timer running */
		if (add_blind_uac() < 0) {
			LM_ERR("failed to add the blind UAC\n");
			return -1;
		}
		/* propagate failure route to new branch
		 * - failure route to be executed if the branch is not continued
		 *   before timeout */
		t->uac[t->async_backup.blind_uac].on_failure = t->on_failure;
		t->flags |= T_ASYNC_SUSPENDED;
	} else {
		LM_DBG("this is a suspend on reply - setting msg flag to SUSPEND\n");
		msg->msg_flags |= FL_RPL_SUSPENDED;
		/* this is a reply suspend find which branch */

		if (t_check( msg  , &branch )==-1){
			LOG(L_ERR, "ERROR: t_suspend_reply: " \
				"failed find UAC branch\n");
			return -1; 
		}
		LM_DBG("found a a match with branch id [%d] - "
				"cloning reply message to t->uac[branch].reply\n", branch);

		sip_msg_len = 0;
		t->uac[branch].reply = sip_msg_cloner( msg, &sip_msg_len );

		if (! t->uac[branch].reply ) {
			LOG(L_ERR, "can't alloc' clone memory\n");
			return -1;
		}
		t->uac[branch].end_reply = ((char*)t->uac[branch].reply) + sip_msg_len;

		LM_DBG("saving transaction data\n");
		t->uac[branch].reply->flags = msg->flags;
		t->flags |= T_ASYNC_SUSPENDED;
	}

	*hash_index = t->hash_index;
	*label = t->label;



	/* backup some extra info that can be used in continuation logic */
	t->async_backup.backup_route = get_route_type();
	t->async_backup.backup_branch = get_t_branch();
	t->async_backup.ruri_new = ruri_get_forking_state();


	return 0;
}
Ejemplo n.º 27
0
void test_getcwd()
{
  char *str = getcwd(NULL, 0);
  t_check(str != NULL);
  free(str);
}
Ejemplo n.º 28
0
inline static int w_t_check(struct sip_msg* msg, char* str, char* str2)
{
	return t_check( msg , 0  ) ? 1 : -1;
}