MT#60480 Limitation of origin id/ver to 64bits (unsigned long long)

SDP session origin id and version are limited by it's size
to 64 bits (8 bytes), that is because we are using `unsigned long long`
type for both id and version. Hence the maximum value it can hold
is two sixty-forth power, so equals: 18,446,744,073,709,551,615

In case one intentionally sets it to something like:
"o=- 18446744073709551615 18446744073709551615 IN IP4 192.168.0.1"

SEMS gets overwhelmed with that conversion inside the code make
it just to a string literal 'F'.

To overcome it, just use __uint128 (which is of 128bits size)
for the session origin id and version.

Change-Id: I2ad9659aa81dad79969749053dc3fd0d69e2cbd2
mr12.5
Donat Zenichev 2 years ago
parent ced4a52c5d
commit f343df5587

@ -1891,7 +1891,7 @@ void CallLeg::createResumeRequest(AmSdp &sdp)
* be good enough for unholding (might be held already with zero conncetions) */
/* keep sessV incremented each time sending SDP offer (hold/resume) */
non_hold_sdp.origin.sessV++;
DBG("Increasing session version in SDP origin line to %llu", non_hold_sdp.origin.sessV);
DBG("Increasing session version in SDP origin line to %s", uint128ToStr(non_hold_sdp.origin.sessV).c_str());
if (!non_hold_sdp.media.empty()) {
sdp = non_hold_sdp;

@ -1847,7 +1847,7 @@ void SBCCallLeg::createHoldRequest(AmSdp &sdp)
} else {
/* increase sessV */
sdp.origin.sessV++;
TRACE("Increasing session version in SDP origin line to %llu", sdp.origin.sessV);
TRACE("Increasing session version in SDP origin line to %s", uint128ToStr(sdp.origin.sessV).c_str());
}
AmB2BMedia *ms = getMediaSession();

@ -616,7 +616,7 @@ void AmB2BSession::saveLocalSdpOrigin(const AmSdp& sdp)
previous_origin_sessId = sdp.origin.sessId;
previous_origin_sessV = sdp.origin.sessV;
DBG("Remembering initial SDP Origin (Id %s V %s)\n",
ulonglong2str(sdp.origin.sessId).c_str(), ulonglong2str(sdp.origin.sessV).c_str());
uint128ToStr(sdp.origin.sessId).c_str(), uint128ToStr(sdp.origin.sessV).c_str());
}
}
@ -656,10 +656,10 @@ void AmB2BSession::updateLocalSdpOrigin(AmSdp& sdp) {
// remember the current SDP for the next time
previous_sdp = sdp;
DBG("SDP changed; updating Origin (Id %s V %s)\n",
ulonglong2str(sdp.origin.sessId).c_str(), ulonglong2str(sdp.origin.sessV).c_str());
uint128ToStr(sdp.origin.sessId).c_str(), uint128ToStr(sdp.origin.sessV).c_str());
} else {
DBG("SDP unchanged; keeping Origin (Id %s V %s)\n",
ulonglong2str(sdp.origin.sessId).c_str(), ulonglong2str(sdp.origin.sessV).c_str());
uint128ToStr(sdp.origin.sessId).c_str(), uint128ToStr(sdp.origin.sessV).c_str());
}
}
}

@ -161,8 +161,8 @@ private:
// we have to use the same "o=" line with potentially increasing session version in SDP
SdpOrigin sdp_origin;
AmSdp previous_sdp;
unsigned long long previous_origin_sessId;
unsigned long long previous_origin_sessV;
__uint128_t previous_origin_sessId;
__uint128_t previous_origin_sessV;
protected:
/** Tell if the session should

@ -28,6 +28,7 @@
#include "AmOfferAnswer.h"
#include "AmSipDialog.h"
#include "AmUtils.h"
#include "AmSipHeaders.h"
#include "log.h"
@ -380,8 +381,8 @@ int AmOfferAnswer::onReplyOut(AmSipReply& reply)
} else {
force_no_sdp_update = (sdp_local.origin.sessV == parser_sdp.origin.sessV);
if (force_no_sdp_update)
DBG("Forcing no OA state update (no SDP changes, same session version: was <%llu>, now is <%llu>).\n",
sdp_local.origin.sessV, parser_sdp.origin.sessV);
DBG("Forcing no OA state update (no SDP changes, same session version: was <%s>, now is <%s>).\n",
uint128ToStr(sdp_local.origin.sessV).c_str(), uint128ToStr(parser_sdp.origin.sessV).c_str());
}
}

@ -315,8 +315,8 @@ int AmSdp::parse(const char* _sdp_msg)
void AmSdp::print(string& body) const
{
string out_buf = "v="+int2str(version)+"\r\n"
"o="+origin.user+" "+ulonglong2str(origin.sessId)+" "+
ulonglong2str(origin.sessV)+" IN ";
"o="+origin.user+" "+uint128ToStr(origin.sessId)+" "+
uint128ToStr(origin.sessV)+" IN ";
if (!origin.conn.address.empty())
if (origin.conn.address.find(".") != std::string::npos)
@ -1285,7 +1285,7 @@ static void parse_sdp_origin(AmSdp* sdp_msg, char* s)
break;
}
string id(origin_line, int(next-origin_line)-1);
str2ull(id, origin.sessId);
str2uint128(id, origin.sessId);
origin_line = next;
origin_st = VERSION_ST;
break;
@ -1300,7 +1300,7 @@ static void parse_sdp_origin(AmSdp* sdp_msg, char* s)
break;
}
string version(origin_line, int(next-origin_line)-1);
str2ull(version, origin.sessV);
str2uint128(version, origin.sessV);
origin_line = next;
origin_st = NETTYPE;
break;

@ -28,6 +28,8 @@
#ifndef __SdpParser__
#define __SdpParser__
#include <stdio.h>
#include <string>
#include <map>
#include <vector>
@ -81,8 +83,8 @@ struct SdpConnection
struct SdpOrigin
{
string user;
unsigned long long sessId;
unsigned long long sessV;
__uint128_t sessId;
__uint128_t sessV;
SdpConnection conn;
SdpOrigin() : user(), conn() {}

@ -56,6 +56,18 @@
static char _int2str_lookup[] = { '0', '1', '2', '3', '4', '5', '6' , '7', '8', '9' };
string uint128ToStr(__uint128_t val)
{
std::string result;
/* support 0 values */
if (val == 0)
return "0";
while (val != 0) {
result.insert(result.begin(), '0' + (val % 10));
val /= 10;
}
return result;
}
string ull2str(unsigned long long val)
{
@ -375,6 +387,27 @@ bool str2long(char*& str, long& result, char sep)
return false;
}
bool str2uint128(const string& str, __uint128_t & result)
{
char* s = (char*)str.c_str();
result = str2uint128(s);
return (result ? true : false);
}
__uint128_t str2uint128(const char* str) {
__uint128_t result = 0;
while (*str) {
if (*str < '0' || *str > '9') {
DBG("Invalid character in string '%s'\n", str);
result = 0;
break;
}
result = result * 10 + (*str - '0');
str++;
}
return result;
}
// long int could probably be the same size as int
bool str2ull(const string& str, unsigned long long& result)
{

@ -64,6 +64,11 @@ typedef unsigned char HASHHEX[HASHHEXLEN+1];
*/
string ull2str(unsigned long long val);
/**
* Convert an unsigned int128 to a string.
*/
string uint128ToStr(__uint128_t val);
/**
* Convert an int to a string.
*/
@ -170,6 +175,20 @@ bool str2long(const string& str, long& result);
*/
bool str2long(char*& str, long& result, char sep = ' ');
/**
* Convert a string to a unsigned int128.
* @param str [in] string to convert.
* @param result [out] result unsinged int128.
* @return true on success.
*/
bool str2uint128(const string& str, __uint128_t & result);
/**
* Convert a char array to a unsigned int128.
* @param str [in] string to convert.
* @return 0 (failed) or converted unsigned int128 value.
*/
__uint128_t str2uint128(const char* str);
/**
* Convert a string to a unsigned long long int.
* @param str [in] string to convert.

Loading…
Cancel
Save