mirror of
				https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
				synced 2025-11-04 05:53:26 +00:00 
			
		
		
		
	rework message handling
This was previously broken and a free endpoint was requirted to dlcx *, additionaly globally handling this is difficult due to different response codes, so just do it in the functions, they know best. Change-Id: I8cbbe5936067ea1caa7935e8d14908ac5c4010bd
This commit is contained in:
		@@ -97,10 +97,6 @@ struct mgcp_request {
 | 
				
			|||||||
	/* function pointer to the request handler */
 | 
						/* function pointer to the request handler */
 | 
				
			||||||
	struct msgb *(*handle_request)(struct mgcp_request_data *data);
 | 
						struct msgb *(*handle_request)(struct mgcp_request_data *data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* true if the request requires an endpoint, false if only a trunk
 | 
					 | 
				
			||||||
	 * is sufficient. (corner cases, e.g. wildcarded DLCX) */
 | 
					 | 
				
			||||||
	bool require_endp;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* a human readable name that describes the request */
 | 
						/* a human readable name that describes the request */
 | 
				
			||||||
	char *debug_name;
 | 
						char *debug_name;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -112,32 +108,34 @@ static struct msgb *handle_modify_con(struct mgcp_request_data *data);
 | 
				
			|||||||
static struct msgb *handle_rsip(struct mgcp_request_data *data);
 | 
					static struct msgb *handle_rsip(struct mgcp_request_data *data);
 | 
				
			||||||
static struct msgb *handle_noti_req(struct mgcp_request_data *data);
 | 
					static struct msgb *handle_noti_req(struct mgcp_request_data *data);
 | 
				
			||||||
static const struct mgcp_request mgcp_requests[] = {
 | 
					static const struct mgcp_request mgcp_requests[] = {
 | 
				
			||||||
	{ .name = "AUEP",
 | 
						{ .name = "AUEP", .handle_request = handle_audit_endpoint, .debug_name = "AuditEndpoint" },
 | 
				
			||||||
	  .handle_request = handle_audit_endpoint,
 | 
						{
 | 
				
			||||||
	  .debug_name = "AuditEndpoint",
 | 
							.name = "CRCX",
 | 
				
			||||||
	  .require_endp = true },
 | 
					 | 
				
			||||||
	{ .name = "CRCX",
 | 
					 | 
				
			||||||
		.handle_request = handle_create_con,
 | 
							.handle_request = handle_create_con,
 | 
				
			||||||
		.debug_name = "CreateConnection",
 | 
							.debug_name = "CreateConnection",
 | 
				
			||||||
	  .require_endp = true },
 | 
						},
 | 
				
			||||||
	{ .name = "DLCX",
 | 
						{
 | 
				
			||||||
 | 
							.name = "DLCX",
 | 
				
			||||||
		.handle_request = handle_delete_con,
 | 
							.handle_request = handle_delete_con,
 | 
				
			||||||
		.debug_name = "DeleteConnection",
 | 
							.debug_name = "DeleteConnection",
 | 
				
			||||||
	  .require_endp = false },
 | 
						},
 | 
				
			||||||
	{ .name = "MDCX",
 | 
						{
 | 
				
			||||||
 | 
							.name = "MDCX",
 | 
				
			||||||
		.handle_request = handle_modify_con,
 | 
							.handle_request = handle_modify_con,
 | 
				
			||||||
		.debug_name = "ModifiyConnection",
 | 
							.debug_name = "ModifiyConnection",
 | 
				
			||||||
	  .require_endp = true },
 | 
						},
 | 
				
			||||||
	{ .name = "RQNT",
 | 
						{
 | 
				
			||||||
 | 
							.name = "RQNT",
 | 
				
			||||||
		.handle_request = handle_noti_req,
 | 
							.handle_request = handle_noti_req,
 | 
				
			||||||
		.debug_name = "NotificationRequest",
 | 
							.debug_name = "NotificationRequest",
 | 
				
			||||||
	  .require_endp = true },
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* SPEC extension */
 | 
						/* SPEC extension */
 | 
				
			||||||
	{ .name = "RSIP",
 | 
						{
 | 
				
			||||||
 | 
							.name = "RSIP",
 | 
				
			||||||
		.handle_request = handle_rsip,
 | 
							.handle_request = handle_rsip,
 | 
				
			||||||
		.debug_name = "ReSetInProgress",
 | 
							.debug_name = "ReSetInProgress",
 | 
				
			||||||
	  .require_endp = true },
 | 
						},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Initalize transcoder */
 | 
					/* Initalize transcoder */
 | 
				
			||||||
@@ -420,15 +418,6 @@ struct msgb *mgcp_handle_message(struct mgcp_config *cfg, struct msgb *msg)
 | 
				
			|||||||
	/* Find an appropriate handler for the current request and execute it */
 | 
						/* Find an appropriate handler for the current request and execute it */
 | 
				
			||||||
	for (i = 0; i < ARRAY_SIZE(mgcp_requests); i++) {
 | 
						for (i = 0; i < ARRAY_SIZE(mgcp_requests); i++) {
 | 
				
			||||||
		if (strcmp(mgcp_requests[i].name, rq.name) == 0) {
 | 
							if (strcmp(mgcp_requests[i].name, rq.name) == 0) {
 | 
				
			||||||
			/* Check if the request requires and endpoint, if yes, check if we have it, otherwise don't
 | 
					 | 
				
			||||||
			 * execute the request handler. */
 | 
					 | 
				
			||||||
			if (mgcp_requests[i].require_endp && !rq.endp) {
 | 
					 | 
				
			||||||
				LOGP(DLMGCP, LOGL_ERROR,
 | 
					 | 
				
			||||||
				     "%s: the request handler \"%s\" requires an endpoint resource for \"%s\", which is not available -- abort\n",
 | 
					 | 
				
			||||||
				     rq.name, mgcp_requests[i].debug_name, pdata.epname);
 | 
					 | 
				
			||||||
				return create_err_response(rq.trunk, NULL, -rq.mgcp_cause, rq.name, pdata.trans);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			/* Execute request handler */
 | 
								/* Execute request handler */
 | 
				
			||||||
			if (rq.endp)
 | 
								if (rq.endp)
 | 
				
			||||||
				LOGP(DLMGCP, LOGL_INFO,
 | 
									LOGP(DLMGCP, LOGL_INFO,
 | 
				
			||||||
@@ -459,6 +448,11 @@ struct msgb *mgcp_handle_message(struct mgcp_config *cfg, struct msgb *msg)
 | 
				
			|||||||
static struct msgb *handle_audit_endpoint(struct mgcp_request_data *rq)
 | 
					static struct msgb *handle_audit_endpoint(struct mgcp_request_data *rq)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	LOGPENDP(rq->endp, DLMGCP, LOGL_NOTICE, "AUEP: auditing endpoint ...\n");
 | 
						LOGPENDP(rq->endp, DLMGCP, LOGL_NOTICE, "AUEP: auditing endpoint ...\n");
 | 
				
			||||||
 | 
						if (!rq->endp || !mgcp_endp_avail(rq->endp)) {
 | 
				
			||||||
 | 
							LOGPENDP(rq->endp, DLMGCP, LOGL_ERROR, "AUEP: selected endpoint not available!\n");
 | 
				
			||||||
 | 
							return create_err_response(rq->trunk, NULL, 501, "AUEP", rq->pdata->trans);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return create_ok_response(rq->trunk, rq->endp, 200, "AUEP", rq->pdata->trans);
 | 
						return create_ok_response(rq->trunk, rq->endp, 200, "AUEP", rq->pdata->trans);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -853,6 +847,13 @@ static struct msgb *handle_create_con(struct mgcp_request_data *rq)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	LOGPENDP(endp, DLMGCP, LOGL_NOTICE, "CRCX: creating new connection ...\n");
 | 
						LOGPENDP(endp, DLMGCP, LOGL_NOTICE, "CRCX: creating new connection ...\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* we must have a free ep */
 | 
				
			||||||
 | 
						if (!endp) {
 | 
				
			||||||
 | 
							rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_CRCX_FAIL_AVAIL));
 | 
				
			||||||
 | 
							LOGPENDP(endp, DLMGCP, LOGL_ERROR, "CRCX: no free endpoints available!\n");
 | 
				
			||||||
 | 
							return create_err_response(rq->trunk, NULL, 403, "CRCX", pdata->trans);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!mgcp_endp_avail(endp)) {
 | 
						if (!mgcp_endp_avail(endp)) {
 | 
				
			||||||
		rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_CRCX_FAIL_AVAIL));
 | 
							rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_CRCX_FAIL_AVAIL));
 | 
				
			||||||
		LOGPENDP(endp, DLMGCP, LOGL_ERROR,
 | 
							LOGPENDP(endp, DLMGCP, LOGL_ERROR,
 | 
				
			||||||
@@ -1110,13 +1111,6 @@ static struct msgb *handle_modify_con(struct mgcp_request_data *rq)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	LOGPENDP(endp, DLMGCP, LOGL_NOTICE, "MDCX: modifying existing connection ...\n");
 | 
						LOGPENDP(endp, DLMGCP, LOGL_NOTICE, "MDCX: modifying existing connection ...\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!mgcp_endp_avail(endp)) {
 | 
					 | 
				
			||||||
		rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_MDCX_FAIL_AVAIL));
 | 
					 | 
				
			||||||
		LOGPENDP(endp, DLMGCP, LOGL_ERROR,
 | 
					 | 
				
			||||||
			 "MDCX: selected endpoint not available!\n");
 | 
					 | 
				
			||||||
		return create_err_response(endp, NULL, 501, "MDCX", pdata->trans);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Prohibit wildcarded requests */
 | 
						/* Prohibit wildcarded requests */
 | 
				
			||||||
	if (rq->wildcarded) {
 | 
						if (rq->wildcarded) {
 | 
				
			||||||
		LOGPENDP(endp, DLMGCP, LOGL_ERROR,
 | 
							LOGPENDP(endp, DLMGCP, LOGL_ERROR,
 | 
				
			||||||
@@ -1125,6 +1119,11 @@ static struct msgb *handle_modify_con(struct mgcp_request_data *rq)
 | 
				
			|||||||
		return create_err_response(rq->trunk, endp, 507, "MDCX", pdata->trans);
 | 
							return create_err_response(rq->trunk, endp, 507, "MDCX", pdata->trans);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!endp || !mgcp_endp_avail(endp)) {
 | 
				
			||||||
 | 
							rate_ctr_inc(rate_ctr_group_get_ctr(rate_ctrs, MGCP_MDCX_FAIL_AVAIL));
 | 
				
			||||||
 | 
							LOGPENDP(endp, DLMGCP, LOGL_ERROR, "MDCX: selected endpoint not available!\n");
 | 
				
			||||||
 | 
							return create_err_response(rq->trunk, NULL, 501, "MDCX", pdata->trans);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if (llist_count(&endp->conns) <= 0) {
 | 
						if (llist_count(&endp->conns) <= 0) {
 | 
				
			||||||
		LOGPENDP(endp, DLMGCP, LOGL_ERROR,
 | 
							LOGPENDP(endp, DLMGCP, LOGL_ERROR,
 | 
				
			||||||
			 "MDCX: endpoint is not holding a connection.\n");
 | 
								 "MDCX: endpoint is not holding a connection.\n");
 | 
				
			||||||
@@ -1343,6 +1342,19 @@ static struct msgb *handle_delete_con(struct mgcp_request_data *rq)
 | 
				
			|||||||
		return create_err_response(endp, endp, 515, "DLCX", pdata->trans);
 | 
							return create_err_response(endp, endp, 515, "DLCX", pdata->trans);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Handle wildcarded DLCX that refers to the whole trunk. This means
 | 
				
			||||||
 | 
						 * that we walk over all endpoints on the trunk in order to drop all
 | 
				
			||||||
 | 
						 * connections on the trunk. (see also RFC3435 Annex F.7) */
 | 
				
			||||||
 | 
						if (rq->wildcarded) {
 | 
				
			||||||
 | 
							int num_conns = 0;
 | 
				
			||||||
 | 
							for (i = 0; i < trunk->number_endpoints; i++) {
 | 
				
			||||||
 | 
								num_conns += llist_count(&trunk->endpoints[i]->conns);
 | 
				
			||||||
 | 
								mgcp_endp_release(trunk->endpoints[i]);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							rate_ctr_add(rate_ctr_group_get_ctr(rate_ctrs, MGCP_DLCX_SUCCESS), num_conns);
 | 
				
			||||||
 | 
							return create_ok_response(trunk, NULL, 200, "DLCX", pdata->trans);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for_each_line(line, pdata->save) {
 | 
						for_each_line(line, pdata->save) {
 | 
				
			||||||
		if (!mgcp_check_param(endp, trunk, line))
 | 
							if (!mgcp_check_param(endp, trunk, line))
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
@@ -1392,19 +1404,6 @@ static struct msgb *handle_delete_con(struct mgcp_request_data *rq)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Handle wildcarded DLCX that refers to the whole trunk. This means
 | 
					 | 
				
			||||||
	 * that we walk over all endpoints on the trunk in order to drop all
 | 
					 | 
				
			||||||
	 * connections on the trunk. (see also RFC3435 Annex F.7) */
 | 
					 | 
				
			||||||
	if (rq->wildcarded) {
 | 
					 | 
				
			||||||
		int num_conns = 0;
 | 
					 | 
				
			||||||
		for (i = 0; i < trunk->number_endpoints; i++) {
 | 
					 | 
				
			||||||
			num_conns += llist_count(&trunk->endpoints[i]->conns);
 | 
					 | 
				
			||||||
			mgcp_endp_release(trunk->endpoints[i]);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		rate_ctr_add(rate_ctr_group_get_ctr(rate_ctrs, MGCP_DLCX_SUCCESS), num_conns);
 | 
					 | 
				
			||||||
		return create_ok_response(trunk, NULL, 200, "DLCX", pdata->trans);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* The logic does not permit to go past this point without having the
 | 
						/* The logic does not permit to go past this point without having the
 | 
				
			||||||
	 * the endp pointer populated. */
 | 
						 * the endp pointer populated. */
 | 
				
			||||||
	OSMO_ASSERT(endp);
 | 
						OSMO_ASSERT(endp);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user