mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 10:47:18 +00:00 
			
		
		
		
	Merge "chan_sip: bigger buffers for headers, better failure mode"
This commit is contained in:
		| @@ -14154,9 +14154,10 @@ static void build_contact(struct sip_pvt *p, struct sip_request *req, int incomi | ||||
| /*! \brief Initiate new SIP request to peer/user */ | ||||
| static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmethod, const char * const explicit_uri) | ||||
| { | ||||
| 	struct ast_str *invite = ast_str_alloca(256); | ||||
| 	char from[256]; | ||||
| 	char to[256]; | ||||
| #define SIPHEADER 256 | ||||
| 	struct ast_str *invite = ast_str_create(SIPHEADER); | ||||
| 	struct ast_str *from = ast_str_create(SIPHEADER); | ||||
| 	struct ast_str *to = ast_str_create(SIPHEADER); | ||||
| 	char tmp_n[SIPBUFSIZE/2];	/* build a local copy of 'n' if needed */ | ||||
| 	char tmp_l[SIPBUFSIZE/2];	/* build a local copy of 'l' if needed */ | ||||
| 	const char *l = NULL;	/* XXX what is this, exactly ? */ | ||||
| @@ -14258,34 +14259,40 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmetho | ||||
| 	ourport = (p->fromdomainport && (p->fromdomainport != STANDARD_SIP_PORT)) ? p->fromdomainport : ast_sockaddr_port(&p->ourip); | ||||
| 
 | ||||
| 	if (!sip_standard_port(p->socket.type, ourport)) { | ||||
| 		ret = snprintf(from, sizeof(from), "<sip:%s@%s:%d>;tag=%s", tmp_l, d, ourport, p->tag); | ||||
| 		ret = ast_str_set(&from, 0, "<sip:%s@%s:%d>;tag=%s", tmp_l, d, ourport, p->tag); | ||||
| 	} else { | ||||
| 		ret = snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", tmp_l, d, p->tag); | ||||
| 		ret = ast_str_set(&from, 0, "<sip:%s@%s>;tag=%s", tmp_l, d, p->tag); | ||||
| 	} | ||||
| 	if (ret < 0 || ret >= sizeof(from)) { /* a return value of size or more means that the output was truncated */ | ||||
| 	if (ret == AST_DYNSTR_BUILD_FAILED) { | ||||
| 		/* We don't have an escape path from here... */ | ||||
| 		ast_log(LOG_ERROR, "The From header was truncated in call '%s'. This call setup will fail.\n", p->callid); | ||||
| 		/* Make sure that the field contains something non-broken.
 | ||||
| 		   See https://issues.asterisk.org/jira/browse/ASTERISK-26069
 | ||||
| 		*/ | ||||
| 		ast_str_set(&from, 3, "<>"); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	/* If a caller id name was specified, prefix a display name, if there is enough room. */ | ||||
| 	if (cid_has_name || !cid_has_num) { | ||||
| 		size_t written = strlen(from); | ||||
| 		ssize_t left = sizeof(from) - written - 4; /* '"" \0' */ | ||||
| 		if (left > 0) { | ||||
| 			size_t name_len; | ||||
| 			if (sip_cfg.pedanticsipchecking) { | ||||
| 				ast_escape_quoted(n, tmp_n, MIN(left + 1, sizeof(tmp_n))); | ||||
| 				n = tmp_n; | ||||
| 			} | ||||
| 			name_len = strlen(n); | ||||
| 			if (left < name_len) { | ||||
| 				name_len = left; | ||||
| 			} | ||||
| 			memmove(from + name_len + 3, from, written + 1); | ||||
| 			from[0] = '"'; | ||||
| 			memcpy(from + 1, n, name_len); | ||||
| 			from[name_len + 1] = '"'; | ||||
| 			from[name_len + 2] = ' '; | ||||
| 		size_t written = ast_str_strlen(from); | ||||
| 		size_t name_len; | ||||
| 		if (sip_cfg.pedanticsipchecking) { | ||||
| 			ast_escape_quoted(n, tmp_n, sizeof(tmp_n)); | ||||
| 			n = tmp_n; | ||||
| 		} | ||||
| 		name_len = strlen(n); | ||||
| 		ret = ast_str_make_space(&from, name_len + written + 4); | ||||
| 
 | ||||
| 		if (ret == 0) { | ||||
| 			/* needed again, as ast_str_make_space coud've changed the pointer */ | ||||
| 			char *from_buf = ast_str_buffer(from); | ||||
| 
 | ||||
| 			memmove(from_buf + name_len + 3, from_buf, written + 1); | ||||
| 			from_buf[0] = '"'; | ||||
| 			memcpy(from_buf + 1, n, name_len); | ||||
| 			from_buf[name_len + 1] = '"'; | ||||
| 			from_buf[name_len + 2] = ' '; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| @@ -14328,24 +14335,28 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmetho | ||||
|  		/*! \todo Need to add back the VXML URL here at some point, possibly use build_string for all this junk */ | ||||
|  		if (!strchr(p->todnid, '@')) { | ||||
|  			/* We have no domain in the dnid */ | ||||
| 			ret = snprintf(to, sizeof(to), "<sip:%s@%s>%s%s", p->todnid, p->tohost, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag); | ||||
| 			ret = ast_str_set(&to, 0, "<sip:%s@%s>%s%s", p->todnid, p->tohost, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag); | ||||
|  		} else { | ||||
| 			ret = snprintf(to, sizeof(to), "<sip:%s>%s%s", p->todnid, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag); | ||||
| 			ret = ast_str_set(&to, 0, "<sip:%s>%s%s", p->todnid, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag); | ||||
|  		} | ||||
|  	} else { | ||||
|  		if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { | ||||
|  			/* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */ | ||||
| 			ret = snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "sip:" : ""), p->uri, p->theirtag); | ||||
| 			ret = ast_str_set(&to, 0, "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "sip:" : ""), p->uri, p->theirtag); | ||||
|  		} else if (p->options && p->options->vxml_url) { | ||||
|  			/* If there is a VXML URL append it to the SIP URL */ | ||||
| 			ret = snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url); | ||||
| 			ret = ast_str_set(&to, 0, "<%s>;%s", p->uri, p->options->vxml_url); | ||||
|  		} else { | ||||
| 			ret = snprintf(to, sizeof(to), "<%s>", p->uri); | ||||
| 			ret = ast_str_set(&to, 0, "<%s>", p->uri); | ||||
| 		} | ||||
|  	} | ||||
| 	if (ret < 0 || ret >= sizeof(to)) { /* a return value of size or more means that the output was truncated */ | ||||
| 	if (ret == AST_DYNSTR_BUILD_FAILED) { | ||||
| 		/* We don't have an escape path from here... */ | ||||
| 		ast_log(LOG_ERROR, "The To header was truncated in call '%s'. This call setup will fail.\n", p->callid); | ||||
| 		/* Make sure that the field contains something non-broken.
 | ||||
| 		   See https://issues.asterisk.org/jira/browse/ASTERISK-26069
 | ||||
| 		*/ | ||||
| 		ast_str_set(&to, 3, "<>"); | ||||
| 	} | ||||
| 
 | ||||
| 	init_req(req, sipmethod, p->uri); | ||||
| @@ -14360,8 +14371,8 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmetho | ||||
| 	 */ | ||||
| 	add_route(req, &p->route, 0); | ||||
| 
 | ||||
| 	add_header(req, "From", from); | ||||
| 	add_header(req, "To", to); | ||||
| 	add_header(req, "From", ast_str_buffer(from)); | ||||
| 	add_header(req, "To", ast_str_buffer(to)); | ||||
| 	ast_string_field_set(p, exten, l); | ||||
| 	build_contact(p, req, 0); | ||||
| 	add_header(req, "Contact", p->our_contact); | ||||
| @@ -14370,6 +14381,10 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmetho | ||||
| 	if (!ast_strlen_zero(global_useragent)) { | ||||
| 		add_header(req, "User-Agent", global_useragent); | ||||
| 	} | ||||
| 
 | ||||
| 	ast_free(from); | ||||
| 	ast_free(to); | ||||
| 	ast_free(invite); | ||||
| } | ||||
| 
 | ||||
| /*! \brief Add "Diversion" header to outgoing message
 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user