[rtmpdump] r107 - in trunk: amf.c amf.h handshake.h rtmp.c rtmp.h rtmpdump.c streams.c
hyc
subversion at mplayerhq.hu
Tue Dec 22 05:55:20 CET 2009
Author: hyc
Date: Tue Dec 22 05:55:19 2009
New Revision: 107
Log:
Change AMF_Encode* APIs to include buffer end checking, restructure...
Modified:
trunk/amf.c
trunk/amf.h
trunk/handshake.h
trunk/rtmp.c
trunk/rtmp.h
trunk/rtmpdump.c
trunk/streams.c
Modified: trunk/amf.c
==============================================================================
--- trunk/amf.c Tue Dec 22 01:50:58 2009 (r106)
+++ trunk/amf.c Tue Dec 22 05:55:19 2009 (r107)
@@ -113,50 +113,64 @@ AMF_DecodeBoolean(const char *data)
return *data != 0;
}
-int
-AMF_EncodeInt16(char *output, short nVal)
+char *
+AMF_EncodeInt16(char *output, char *outend, short nVal)
{
+ if (output+2 >= outend)
+ return NULL;
+
output[1] = nVal & 0xff;
output[0] = nVal >> 8;
- return 2;
+ return output+2;
}
-int
-AMF_EncodeInt24(char *output, int nVal)
+char *
+AMF_EncodeInt24(char *output, char *outend, int nVal)
{
+ if (output+3 >= outend)
+ return NULL;
+
output[2] = nVal & 0xff;
output[1] = nVal >> 8;
output[0] = nVal >> 16;
- return 3;
+ return output+3;
}
-int
-AMF_EncodeInt32(char *output, int nVal)
+char *
+AMF_EncodeInt32(char *output, char *outend, int nVal)
{
+ if (output+4 >= outend)
+ return NULL;
+
output[3] = nVal & 0xff;
output[2] = nVal >> 8;
output[1] = nVal >> 16;
output[0] = nVal >> 24;
- return 4;
+ return output+4;
}
-int
-AMF_EncodeString(char *output, const AVal * bv)
+char *
+AMF_EncodeString(char *output, char *outend, const AVal * bv)
{
- char *buf = output;
- *buf++ = AMF_STRING;
+ if (output + 1 + 2 + bv->av_len >= outend)
+ return NULL;
- buf += AMF_EncodeInt16(buf, bv->av_len);
+ *output++ = AMF_STRING;
- memcpy(buf, bv->av_val, bv->av_len);
- buf += bv->av_len;
+ output = AMF_EncodeInt16(output, outend, bv->av_len);
- return buf - output;
+ memcpy(output, bv->av_val, bv->av_len);
+ output += bv->av_len;
+
+ return output;
}
-int
-AMF_EncodeNumber(char *output, double dVal)
+char *
+AMF_EncodeNumber(char *output, char *outend, double dVal)
{
+ if (output+1+8 >= outend)
+ return NULL;
+
*output++ = AMF_NUMBER; // type: Number
#if __FLOAT_WORD_ORDER == __BYTE_ORDER
@@ -209,19 +223,59 @@ AMF_EncodeNumber(char *output, double dV
#endif
#endif
- return 9;
+ return output+8;
}
-int
-AMF_EncodeBoolean(char *output, bool bVal)
+char *
+AMF_EncodeBoolean(char *output, char *outend, bool bVal)
{
- char *buf = output;
+ if (output+2 >= outend)
+ return NULL;
- *buf++ = AMF_BOOLEAN;
+ *output++ = AMF_BOOLEAN;
- *buf = bVal ? 0x01 : 0x00;
+ *output++ = bVal ? 0x01 : 0x00;
- return 2;
+ return output;
+}
+
+char *
+AMF_EncodeNamedString(char *output, char *outend, const AVal * strName, const AVal * strValue)
+{
+ if (output+2+strName->av_len >= outend)
+ return NULL;
+ output = AMF_EncodeInt16(output, outend, strName->av_len);
+
+ memcpy(output, strName->av_val, strName->av_len);
+ output += strName->av_len;
+
+ return AMF_EncodeString(output, outend, strValue);
+}
+
+char *
+AMF_EncodeNamedNumber(char *output, char *outend, const AVal * strName, double dVal)
+{
+ if (output+2+strName->av_len >= outend)
+ return NULL;
+ output = AMF_EncodeInt16(output, outend, strName->av_len);
+
+ memcpy(output, strName->av_val, strName->av_len);
+ output += strName->av_len;
+
+ return AMF_EncodeNumber(output, outend, dVal);
+}
+
+char *
+AMF_EncodeNamedBoolean(char *output, char *outend, const AVal * strName, bool bVal)
+{
+ if (output+2+strName->av_len >= outend)
+ return NULL;
+ output = AMF_EncodeInt16(output, outend, strName->av_len);
+
+ memcpy(output, strName->av_val, strName->av_len);
+ output += strName->av_len;
+
+ return AMF_EncodeBoolean(output, outend, bVal);
}
void
@@ -272,16 +326,14 @@ AMFProp_IsValid(AMFObjectProperty * prop
return prop->p_type != AMF_INVALID;
}
-int
-AMFProp_Encode(AMFObjectProperty * prop, char *pBuffer, int nSize)
+char *
+AMFProp_Encode(AMFObjectProperty * prop, char *pBuffer, char *pBufEnd)
{
- int nBytes = 0;
-
if (prop->p_type == AMF_INVALID)
- return -1;
+ return NULL;
- if (prop->p_type != AMF_NULL && nSize < prop->p_name.av_len + 2 + 1)
- return -1;
+ if (prop->p_type != AMF_NULL && pBuffer + prop->p_name.av_len + 2 + 1 >= pBufEnd)
+ return NULL;
if (prop->p_type != AMF_NULL && prop->p_name.av_len)
{
@@ -289,52 +341,38 @@ AMFProp_Encode(AMFObjectProperty * prop,
*pBuffer++ = prop->p_name.av_len & 0xff;
memcpy(pBuffer, prop->p_name.av_val, prop->p_name.av_len);
pBuffer += prop->p_name.av_len;
- nBytes += prop->p_name.av_len + 2;
- nSize -= nBytes;
}
switch (prop->p_type)
{
case AMF_NUMBER:
- if (nSize < 9)
- return -1;
- nBytes += AMF_EncodeNumber(pBuffer, prop->p_vu.p_number);
+ pBuffer = AMF_EncodeNumber(pBuffer, pBufEnd, prop->p_vu.p_number);
break;
case AMF_BOOLEAN:
- if (nSize < 2)
- return -1;
- nBytes += AMF_EncodeBoolean(pBuffer, prop->p_vu.p_number != 0);
+ pBuffer = AMF_EncodeBoolean(pBuffer, pBufEnd, prop->p_vu.p_number != 0);
break;
case AMF_STRING:
- if (nSize < prop->p_vu.p_aval.av_len + (int) sizeof(short))
- return -1;
- nBytes += AMF_EncodeString(pBuffer, &prop->p_vu.p_aval);
+ pBuffer = AMF_EncodeString(pBuffer, pBufEnd, &prop->p_vu.p_aval);
break;
case AMF_NULL:
- if (nSize < 1)
- return -1;
- *pBuffer = AMF_NULL;
- nBytes += 1;
+ if (pBuffer+1 >= pBufEnd)
+ return NULL;
+ *pBuffer++ = AMF_NULL;
break;
case AMF_OBJECT:
- {
- int nRes = AMF_Encode(&prop->p_vu.p_object, pBuffer, nSize);
- if (nRes == -1)
- return -1;
+ pBuffer = AMF_Encode(&prop->p_vu.p_object, pBuffer, pBufEnd);
+ break;
- nBytes += nRes;
- break;
- }
default:
Log(LOGERROR, "%s, invalid type. %d", __FUNCTION__, prop->p_type);
- return -1;
+ pBuffer = NULL;
};
- return nBytes;
+ return pBuffer;
}
#define AMF3_INTEGER_MAX 268435455
@@ -790,39 +828,37 @@ AMFProp_Reset(AMFObjectProperty * prop)
/* AMFObject */
-int
-AMF_Encode(AMFObject * obj, char *pBuffer, int nSize)
+char *
+AMF_Encode(AMFObject * obj, char *pBuffer, char *pBufEnd)
{
- int nOriginalSize = nSize;
int i;
- if (nSize < 4)
- return -1;
+ if (pBuffer+4 >= pBufEnd)
+ return NULL;
- *pBuffer = AMF_OBJECT;
+ *pBuffer++ = AMF_OBJECT;
for (i = 0; i < obj->o_num; i++)
{
- int nRes = AMFProp_Encode(&obj->o_props[i], pBuffer, nSize);
- if (nRes == -1)
+ char *res = AMFProp_Encode(&obj->o_props[i], pBuffer, pBufEnd);
+ if (res == NULL)
{
Log(LOGERROR, "AMF_Encode - failed to encode property in index %d",
i);
+ break;
}
else
{
- nSize -= nRes;
- pBuffer += nRes;
+ pBuffer = res;
}
}
- if (nSize < 3)
- return -1; // no room for the end marker
+ if (pBuffer + 3 >= pBufEnd)
+ return NULL; // no room for the end marker
- AMF_EncodeInt24(pBuffer, AMF_OBJECT_END);
- nSize -= 3;
+ pBuffer = AMF_EncodeInt24(pBuffer, pBufEnd, AMF_OBJECT_END);
- return nOriginalSize - nSize;
+ return pBuffer;
}
int
@@ -1077,10 +1113,12 @@ void
AMF_Dump(AMFObject * obj)
{
int n;
+ Log(LOGDEBUG, "(object begin)");
for (n = 0; n < obj->o_num; n++)
{
AMFProp_Dump(&obj->o_props[n]);
}
+ Log(LOGDEBUG, "(object end)");
}
void
Modified: trunk/amf.h
==============================================================================
--- trunk/amf.h Tue Dec 22 01:50:58 2009 (r106)
+++ trunk/amf.h Tue Dec 22 05:55:19 2009 (r107)
@@ -80,12 +80,17 @@ extern "C"
int16_t p_UTCoffset;
} AMFObjectProperty;
- int AMF_EncodeString(char *output, const AVal * str);
- int AMF_EncodeNumber(char *output, double dVal);
- int AMF_EncodeInt16(char *output, short nVal);
- int AMF_EncodeInt24(char *output, int nVal);
- int AMF_EncodeInt32(char *output, int nVal);
- int AMF_EncodeBoolean(char *output, bool bVal);
+ char *AMF_EncodeString(char *output, char *outend, const AVal * str);
+ char *AMF_EncodeNumber(char *output, char *outend, double dVal);
+ char *AMF_EncodeInt16(char *output, char *outend, short nVal);
+ char *AMF_EncodeInt24(char *output, char *outend, int nVal);
+ char *AMF_EncodeInt32(char *output, char *outend, int nVal);
+ char *AMF_EncodeBoolean(char *output, char *outend, bool bVal);
+
+ /* Shortcuts for AMFProp_Encode */
+ char *AMF_EncodeNamedString(char *output, char *outend, const AVal * name, const AVal * value);
+ char *AMF_EncodeNamedNumber(char *output, char *outend, const AVal * name, double dVal);
+ char *AMF_EncodeNamedBoolean(char *output, char *outend, const AVal * name, bool bVal);
unsigned short AMF_DecodeInt16(const char *data);
unsigned int AMF_DecodeInt24(const char *data);
@@ -94,7 +99,7 @@ extern "C"
bool AMF_DecodeBoolean(const char *data);
double AMF_DecodeNumber(const char *data);
- int AMF_Encode(AMFObject * obj, char *pBuffer, int nSize);
+ char *AMF_Encode(AMFObject * obj, char *pBuffer, char *pBufEnd);
int AMF_Decode(AMFObject * obj, const char *pBuffer, int nSize,
bool bDecodeName);
int AMF_DecodeArray(AMFObject * obj, const char *pBuffer, int nSize,
@@ -124,7 +129,7 @@ extern "C"
bool AMFProp_IsValid(AMFObjectProperty * prop);
- int AMFProp_Encode(AMFObjectProperty * prop, char *pBuffer, int nSize);
+ char *AMFProp_Encode(AMFObjectProperty * prop, char *pBuffer, char *pBufEnd);
int AMF3Prop_Decode(AMFObjectProperty * prop, const char *pBuffer,
int nSize, bool bDecodeName);
int AMFProp_Decode(AMFObjectProperty * prop, const char *pBuffer,
Modified: trunk/handshake.h
==============================================================================
--- trunk/handshake.h Tue Dec 22 01:50:58 2009 (r106)
+++ trunk/handshake.h Tue Dec 22 05:55:19 2009 (r107)
@@ -414,10 +414,11 @@ HandShake(RTMP * r, bool FP9HandShake)
if (r->Link.SWFHash.av_len)
{
const char swfVerify[] = { 0x01, 0x01 };
+ char *vend = r->Link.SWFVerificationResponse+sizeof(r->Link.SWFVerificationResponse);
memcpy(r->Link.SWFVerificationResponse, swfVerify, 2);
- AMF_EncodeInt32(&r->Link.SWFVerificationResponse[2], r->Link.SWFSize);
- AMF_EncodeInt32(&r->Link.SWFVerificationResponse[6], r->Link.SWFSize);
+ AMF_EncodeInt32(&r->Link.SWFVerificationResponse[2], vend, r->Link.SWFSize);
+ AMF_EncodeInt32(&r->Link.SWFVerificationResponse[6], vend, r->Link.SWFSize);
HMACsha256(r->Link.SWFHash.av_val, SHA256_DIGEST_LENGTH,
&serversig[RTMP_SIG_SIZE - SHA256_DIGEST_LENGTH],
SHA256_DIGEST_LENGTH, &r->Link.SWFVerificationResponse[10]);
@@ -731,10 +732,11 @@ SHandShake(RTMP * r)
if (r->Link.SWFHash.av_len)
{
const char swfVerify[] = { 0x01, 0x01 };
+ char *vend = r->Link.SWFVerificationResponse+sizeof(r->Link.SWFVerificationResponse);
memcpy(r->Link.SWFVerificationResponse, swfVerify, 2);
- AMF_EncodeInt32(&r->Link.SWFVerificationResponse[2], r->Link.SWFSize);
- AMF_EncodeInt32(&r->Link.SWFVerificationResponse[6], r->Link.SWFSize);
+ AMF_EncodeInt32(&r->Link.SWFVerificationResponse[2], vend, r->Link.SWFSize);
+ AMF_EncodeInt32(&r->Link.SWFVerificationResponse[6], vend, r->Link.SWFSize);
HMACsha256(r->Link.SWFHash.av_val, SHA256_DIGEST_LENGTH,
&serversig[RTMP_SIG_SIZE - SHA256_DIGEST_LENGTH],
SHA256_DIGEST_LENGTH, &r->Link.SWFVerificationResponse[10]);
Modified: trunk/rtmp.c
==============================================================================
--- trunk/rtmp.c Tue Dec 22 01:50:58 2009 (r106)
+++ trunk/rtmp.c Tue Dec 22 05:55:19 2009 (r107)
@@ -105,19 +105,12 @@ static void HandleCtrl(RTMP * r, const R
static void HandleServerBW(RTMP * r, const RTMPPacket * packet);
static void HandleClientBW(RTMP * r, const RTMPPacket * packet);
-static int EncodeString(char *output, const AVal * name, const AVal * value);
-static int EncodeNumber(char *output, const AVal * name, double dVal);
-static int EncodeBoolean(char *output, const AVal * name, bool bVal);
-
-static bool SendRTMP(RTMP * r, RTMPPacket * packet, bool queue);
-
-static bool ReadPacket(RTMP * r, RTMPPacket * packet);
static int ReadN(RTMP * r, char *buffer, int n);
static bool WriteN(RTMP * r, const char *buffer, int n);
static bool FillBuffer(RTMP * r);
-int32_t
+uint32_t
RTMP_GetTime()
{
#ifdef _DEBUG
@@ -482,7 +475,7 @@ RTMP_ConnectStream(RTMP * r, double seek
r->m_mediaChannel = 0;
- while (!r->m_bPlaying && RTMP_IsConnected(r) && ReadPacket(r, &packet))
+ while (!r->m_bPlaying && RTMP_IsConnected(r) && RTMP_ReadPacket(r, &packet))
{
if (RTMPPacket_IsReady(&packet))
{
@@ -548,7 +541,7 @@ RTMP_GetNextMediaPacket(RTMP * r, RTMPPa
{
int bHasMediaPacket = 0;
- while (!bHasMediaPacket && RTMP_IsConnected(r) && ReadPacket(r, packet))
+ while (!bHasMediaPacket && RTMP_IsConnected(r) && RTMP_ReadPacket(r, packet))
{
if (!RTMPPacket_IsReady(packet))
{
@@ -883,7 +876,7 @@ static bool
SendConnectPacket(RTMP * r)
{
RTMPPacket packet;
- char pbuf[4096];
+ char pbuf[4096], *pend = pbuf+sizeof(pbuf);
packet.m_nChannel = 0x03; // control channel (invoke)
packet.m_headerType = RTMP_PACKET_SIZE_LARGE;
@@ -894,28 +887,60 @@ SendConnectPacket(RTMP * r)
packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE;
char *enc = packet.m_body;
- enc += AMF_EncodeString(enc, &av_connect);
- enc += AMF_EncodeNumber(enc, 1.0);
+ enc = AMF_EncodeString(enc, pend, &av_connect);
+ enc = AMF_EncodeNumber(enc, pend, 1.0);
*enc++ = AMF_OBJECT;
if (r->Link.app.av_len)
- enc += EncodeString(enc, &av_app, &r->Link.app);
+ {
+ enc = AMF_EncodeNamedString(enc, pend, &av_app, &r->Link.app);
+ if (!enc)
+ return false;
+ }
if (r->Link.flashVer.av_len)
- enc += EncodeString(enc, &av_flashVer, &r->Link.flashVer);
+ {
+ enc = AMF_EncodeNamedString(enc, pend, &av_flashVer, &r->Link.flashVer);
+ if (!enc)
+ return false;
+ }
if (r->Link.swfUrl.av_len)
- enc += EncodeString(enc, &av_swfUrl, &r->Link.swfUrl);
+ {
+ enc = AMF_EncodeNamedString(enc, pend, &av_swfUrl, &r->Link.swfUrl);
+ if (!enc)
+ return false;
+ }
if (r->Link.tcUrl.av_len)
- enc += EncodeString(enc, &av_tcUrl, &r->Link.tcUrl);
-
- enc += EncodeBoolean(enc, &av_fpad, false);
- enc += EncodeNumber(enc, &av_capabilities, 15.0);
- enc += EncodeNumber(enc, &av_audioCodecs, r->m_fAudioCodecs);
- enc += EncodeNumber(enc, &av_videoCodecs, r->m_fVideoCodecs);
- enc += EncodeNumber(enc, &av_videoFunction, 1.0);
+ {
+ enc = AMF_EncodeNamedString(enc, pend, &av_tcUrl, &r->Link.tcUrl);
+ if (!enc)
+ return false;
+ }
+ enc = AMF_EncodeNamedBoolean(enc, pend, &av_fpad, false);
+ if (!enc)
+ return false;
+ enc = AMF_EncodeNamedNumber(enc, pend, &av_capabilities, 15.0);
+ if (!enc)
+ return false;
+ enc = AMF_EncodeNamedNumber(enc, pend, &av_audioCodecs, r->m_fAudioCodecs);
+ if (!enc)
+ return false;
+ enc = AMF_EncodeNamedNumber(enc, pend, &av_videoCodecs, r->m_fVideoCodecs);
+ if (!enc)
+ return false;
+ enc = AMF_EncodeNamedNumber(enc, pend, &av_videoFunction, 1.0);
+ if (!enc)
+ return false;
if (r->Link.pageUrl.av_len)
- enc += EncodeString(enc, &av_pageUrl, &r->Link.pageUrl);
-
- enc += EncodeNumber(enc, &av_objectEncoding, 0.0); // AMF0, AMF3 not supported yet
+ {
+ enc = AMF_EncodeNamedString(enc, pend, &av_pageUrl, &r->Link.pageUrl);
+ if (!enc)
+ return false;
+ }
+ enc = AMF_EncodeNamedNumber(enc, pend, &av_objectEncoding, 0.0); // AMF0, AMF3 not supported yet
+ if (!enc)
+ return false;
+ if (enc+3 >= pend)
+ return false;
*enc++ = 0;
*enc++ = 0; // end of object - 0x00 0x00 0x09
*enc++ = AMF_OBJECT_END;
@@ -923,14 +948,18 @@ SendConnectPacket(RTMP * r)
// add auth string
if (r->Link.auth.av_len)
{
+ if (enc+2 >= pend)
+ return false;
*enc++ = 0x01;
*enc++ = 0x01;
- enc += AMF_EncodeString(enc, &r->Link.auth);
+ enc = AMF_EncodeString(enc, pend, &r->Link.auth);
+ if (!enc)
+ return false;
}
packet.m_nBodySize = enc - packet.m_body;
- return SendRTMP(r, &packet, true);
+ return RTMP_SendPacket(r, &packet, true);
}
SAVC(bgHasStream);
@@ -939,7 +968,7 @@ static bool
SendBGHasStream(RTMP * r, double dId, AVal * playpath)
{
RTMPPacket packet;
- char pbuf[1024];
+ char pbuf[1024], *pend = pbuf+sizeof(pbuf);
packet.m_nChannel = 0x03; // control channel (invoke)
packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM;
@@ -950,15 +979,17 @@ SendBGHasStream(RTMP * r, double dId, AV
packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE;
char *enc = packet.m_body;
- enc += AMF_EncodeString(enc, &av_bgHasStream);
- enc += AMF_EncodeNumber(enc, dId);
+ enc = AMF_EncodeString(enc, pend, &av_bgHasStream);
+ enc = AMF_EncodeNumber(enc, pend, dId);
*enc++ = AMF_NULL;
- enc += AMF_EncodeString(enc, playpath);
+ enc = AMF_EncodeString(enc, pend, playpath);
+ if (enc == NULL)
+ return false;
packet.m_nBodySize = enc - packet.m_body;
- return SendRTMP(r, &packet, true);
+ return RTMP_SendPacket(r, &packet, true);
}
SAVC(createStream);
@@ -967,7 +998,7 @@ static bool
SendCreateStream(RTMP * r, double dStreamId)
{
RTMPPacket packet;
- char pbuf[256];
+ char pbuf[256], *pend = pbuf+sizeof(pbuf);
packet.m_nChannel = 0x03; // control channel (invoke)
packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM;
@@ -978,13 +1009,13 @@ SendCreateStream(RTMP * r, double dStrea
packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE;
char *enc = packet.m_body;
- enc += AMF_EncodeString(enc, &av_createStream);
- enc += AMF_EncodeNumber(enc, dStreamId);
+ enc = AMF_EncodeString(enc, pend, &av_createStream);
+ enc = AMF_EncodeNumber(enc, pend, dStreamId);
*enc++ = AMF_NULL; // NULL
packet.m_nBodySize = enc - packet.m_body;
- return SendRTMP(r, &packet, true);
+ return RTMP_SendPacket(r, &packet, true);
}
SAVC(FCSubscribe);
@@ -993,7 +1024,7 @@ static bool
SendFCSubscribe(RTMP * r, AVal * subscribepath)
{
RTMPPacket packet;
- char pbuf[512];
+ char pbuf[512], *pend = pbuf+sizeof(pbuf);
packet.m_nChannel = 0x03; // control channel (invoke)
packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM;
packet.m_packetType = 0x14; // INVOKE
@@ -1004,14 +1035,17 @@ SendFCSubscribe(RTMP * r, AVal * subscri
Log(LOGDEBUG, "FCSubscribe: %s", subscribepath);
char *enc = packet.m_body;
- enc += AMF_EncodeString(enc, &av_FCSubscribe);
- enc += AMF_EncodeNumber(enc, 4.0);
+ enc = AMF_EncodeString(enc, pend, &av_FCSubscribe);
+ enc = AMF_EncodeNumber(enc, pend, 4.0);
*enc++ = AMF_NULL;
- enc += AMF_EncodeString(enc, subscribepath);
+ enc = AMF_EncodeString(enc, pend, subscribepath);
+
+ if (!enc)
+ return false;
packet.m_nBodySize = enc - packet.m_body;
- return SendRTMP(r, &packet, true);
+ return RTMP_SendPacket(r, &packet, true);
}
SAVC(deleteStream);
@@ -1020,7 +1054,7 @@ static bool
SendDeleteStream(RTMP * r, double dStreamId)
{
RTMPPacket packet;
- char pbuf[256];
+ char pbuf[256], *pend = pbuf+sizeof(pbuf);
packet.m_nChannel = 0x03; // control channel (invoke)
packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM;
@@ -1031,15 +1065,15 @@ SendDeleteStream(RTMP * r, double dStrea
packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE;
char *enc = packet.m_body;
- enc += AMF_EncodeString(enc, &av_deleteStream);
- enc += AMF_EncodeNumber(enc, 0.0);
+ enc = AMF_EncodeString(enc, pend, &av_deleteStream);
+ enc = AMF_EncodeNumber(enc, pend, 0.0);
*enc++ = AMF_NULL;
- enc += AMF_EncodeNumber(enc, dStreamId);
+ enc = AMF_EncodeNumber(enc, pend, dStreamId);
packet.m_nBodySize = enc - packet.m_body;
/* no response expected */
- return SendRTMP(r, &packet, false);
+ return RTMP_SendPacket(r, &packet, false);
}
SAVC(pause);
@@ -1048,7 +1082,7 @@ bool
RTMP_SendPause(RTMP * r, bool DoPause, double dTime)
{
RTMPPacket packet;
- char pbuf[256];
+ char pbuf[256], *pend = pbuf+sizeof(pbuf);
packet.m_nChannel = 0x08; // video channel
packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM;
@@ -1059,15 +1093,15 @@ RTMP_SendPause(RTMP * r, bool DoPause, d
packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE;
char *enc = packet.m_body;
- enc += AMF_EncodeString(enc, &av_pause);
- enc += AMF_EncodeNumber(enc, 0);
+ enc = AMF_EncodeString(enc, pend, &av_pause);
+ enc = AMF_EncodeNumber(enc, pend, 0);
*enc++ = AMF_NULL;
- enc += AMF_EncodeBoolean(enc, DoPause);
- enc += AMF_EncodeNumber(enc, (double) dTime);
+ enc = AMF_EncodeBoolean(enc, pend, DoPause);
+ enc = AMF_EncodeNumber(enc, pend, (double) dTime);
packet.m_nBodySize = enc - packet.m_body;
- return SendRTMP(r, &packet, true);
+ return RTMP_SendPacket(r, &packet, true);
}
SAVC(seek);
@@ -1076,7 +1110,7 @@ static bool
SendSeek(RTMP * r, double dTime)
{
RTMPPacket packet;
- char pbuf[256];
+ char pbuf[256], *pend = pbuf+sizeof(pbuf);
packet.m_nChannel = 0x08; // video channel
packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM;
@@ -1087,21 +1121,21 @@ SendSeek(RTMP * r, double dTime)
packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE;
char *enc = packet.m_body;
- enc += AMF_EncodeString(enc, &av_seek);
- enc += AMF_EncodeNumber(enc, 0);
+ enc = AMF_EncodeString(enc, pend, &av_seek);
+ enc = AMF_EncodeNumber(enc, pend, 0);
*enc++ = AMF_NULL;
- enc += AMF_EncodeNumber(enc, dTime);
+ enc = AMF_EncodeNumber(enc, pend, dTime);
packet.m_nBodySize = enc - packet.m_body;
- return SendRTMP(r, &packet, true);
+ return RTMP_SendPacket(r, &packet, true);
}
static bool
SendServerBW(RTMP * r)
{
RTMPPacket packet;
- char pbuf[256];
+ char pbuf[256], *pend = pbuf+sizeof(pbuf);
packet.m_nChannel = 0x02; // control channel (invoke)
packet.m_headerType = RTMP_PACKET_SIZE_LARGE;
@@ -1113,15 +1147,15 @@ SendServerBW(RTMP * r)
packet.m_nBodySize = 4;
- AMF_EncodeInt32(packet.m_body, r->m_nServerBW);
- return SendRTMP(r, &packet, false);
+ AMF_EncodeInt32(packet.m_body, pend, r->m_nServerBW);
+ return RTMP_SendPacket(r, &packet, false);
}
static bool
SendBytesReceived(RTMP * r)
{
RTMPPacket packet;
- char pbuf[256];
+ char pbuf[256], *pend = pbuf+sizeof(pbuf);
packet.m_nChannel = 0x02; // control channel (invoke)
packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM;
@@ -1133,11 +1167,11 @@ SendBytesReceived(RTMP * r)
packet.m_nBodySize = 4;
- AMF_EncodeInt32(packet.m_body, r->m_nBytesIn); // hard coded for now
+ AMF_EncodeInt32(packet.m_body, pend, r->m_nBytesIn); // hard coded for now
r->m_nBytesInSent = r->m_nBytesIn;
//Log(LOGDEBUG, "Send bytes report. 0x%x (%d bytes)", (unsigned int)m_nBytesIn, m_nBytesIn);
- return SendRTMP(r, &packet, false);
+ return RTMP_SendPacket(r, &packet, false);
}
SAVC(_checkbw);
@@ -1146,7 +1180,7 @@ static bool
SendCheckBW(RTMP * r)
{
RTMPPacket packet;
- char pbuf[256];
+ char pbuf[256], *pend = pbuf+sizeof(pbuf);
packet.m_nChannel = 0x03; // control channel (invoke)
packet.m_headerType = RTMP_PACKET_SIZE_LARGE;
@@ -1157,14 +1191,14 @@ SendCheckBW(RTMP * r)
packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE;
char *enc = packet.m_body;
- enc += AMF_EncodeString(enc, &av__checkbw);
- enc += AMF_EncodeNumber(enc, 0);
+ enc = AMF_EncodeString(enc, pend, &av__checkbw);
+ enc = AMF_EncodeNumber(enc, pend, 0);
*enc++ = AMF_NULL;
packet.m_nBodySize = enc - packet.m_body;
// triggers _onbwcheck and eventually results in _onbwdone
- return SendRTMP(r, &packet, false);
+ return RTMP_SendPacket(r, &packet, false);
}
SAVC(_result);
@@ -1173,7 +1207,7 @@ static bool
SendCheckBWResult(RTMP * r, double txn)
{
RTMPPacket packet;
- char pbuf[256];
+ char pbuf[256], *pend = pbuf+sizeof(pbuf);
packet.m_nChannel = 0x03; // control channel (invoke)
packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM;
@@ -1184,14 +1218,14 @@ SendCheckBWResult(RTMP * r, double txn)
packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE;
char *enc = packet.m_body;
- enc += AMF_EncodeString(enc, &av__result);
- enc += AMF_EncodeNumber(enc, txn);
+ enc = AMF_EncodeString(enc, pend, &av__result);
+ enc = AMF_EncodeNumber(enc, pend, txn);
*enc++ = AMF_NULL;
- enc += AMF_EncodeNumber(enc, (double) r->m_nBWCheckCounter++);
+ enc = AMF_EncodeNumber(enc, pend, (double) r->m_nBWCheckCounter++);
packet.m_nBodySize = enc - packet.m_body;
- return SendRTMP(r, &packet, false);
+ return RTMP_SendPacket(r, &packet, false);
}
SAVC(play);
@@ -1200,7 +1234,7 @@ static bool
SendPlay(RTMP * r)
{
RTMPPacket packet;
- char pbuf[1024];
+ char pbuf[1024], *pend = pbuf+sizeof(pbuf);
packet.m_nChannel = 0x08; // we make 8 our stream channel
packet.m_headerType = RTMP_PACKET_SIZE_LARGE;
@@ -1211,14 +1245,16 @@ SendPlay(RTMP * r)
packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE;
char *enc = packet.m_body;
- enc += AMF_EncodeString(enc, &av_play);
- enc += AMF_EncodeNumber(enc, 0.0); // stream id??
+ enc = AMF_EncodeString(enc, pend, &av_play);
+ enc = AMF_EncodeNumber(enc, pend, 0.0); // stream id??
*enc++ = AMF_NULL;
Log(LOGDEBUG, "%s, seekTime=%.2f, dLength=%d, sending play: %s",
__FUNCTION__, r->Link.seekTime, r->Link.length,
r->Link.playpath.av_val);
- enc += AMF_EncodeString(enc, &r->Link.playpath);
+ enc = AMF_EncodeString(enc, pend, &r->Link.playpath);
+ if (!enc)
+ return false;
// Optional parameters start and len.
@@ -1227,14 +1263,16 @@ SendPlay(RTMP * r)
// -1: plays a live stream
// >=0: plays a recorded streams from 'start' milliseconds
if (r->Link.bLiveStream)
- enc += AMF_EncodeNumber(enc, -1000.0);
+ enc = AMF_EncodeNumber(enc, pend, -1000.0);
else
{
if (r->Link.seekTime > 0.0)
- enc += AMF_EncodeNumber(enc, r->Link.seekTime); // resume from here
+ enc = AMF_EncodeNumber(enc, pend, r->Link.seekTime); // resume from here
else
- enc += AMF_EncodeNumber(enc, 0.0); //-2000.0); // recorded as default, -2000.0 is not reliable since that freezes the player if the stream is not found
+ enc = AMF_EncodeNumber(enc, pend, 0.0); //-2000.0); // recorded as default, -2000.0 is not reliable since that freezes the player if the stream is not found
}
+ if (!enc)
+ return false;
// len: -1, 0, positive number
// -1: plays live or recorded stream to the end (default)
@@ -1242,11 +1280,15 @@ SendPlay(RTMP * r)
// >0: plays a live or recoded stream for 'len' milliseconds
//enc += EncodeNumber(enc, -1.0); // len
if (r->Link.length)
- enc += AMF_EncodeNumber(enc, r->Link.length); // len
+ {
+ enc = AMF_EncodeNumber(enc, pend, r->Link.length); // len
+ if (!enc)
+ return false;
+ }
packet.m_nBodySize = enc - packet.m_body;
- return SendRTMP(r, &packet, true);
+ return RTMP_SendPacket(r, &packet, true);
}
/*
@@ -1271,7 +1313,7 @@ SendCtrl(RTMP * r, short nType, unsigned
Log(LOGDEBUG, "sending ctrl. type: 0x%04x", (unsigned short) nType);
RTMPPacket packet;
- char pbuf[256];
+ char pbuf[256], *pend = pbuf+sizeof(pbuf);
packet.m_nChannel = 0x02; // control channel (ping)
packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM;
@@ -1288,7 +1330,7 @@ SendCtrl(RTMP * r, short nType, unsigned
packet.m_nBodySize = nSize;
char *buf = packet.m_body;
- buf += AMF_EncodeInt16(buf, nType);
+ buf = AMF_EncodeInt16(buf, pend, nType);
if (nType == 0x1B)
{
@@ -1301,13 +1343,13 @@ SendCtrl(RTMP * r, short nType, unsigned
else
{
if (nSize > 2)
- buf += AMF_EncodeInt32(buf, nObject);
+ buf = AMF_EncodeInt32(buf, pend, nObject);
if (nSize > 6)
- buf += AMF_EncodeInt32(buf, nTime);
+ buf = AMF_EncodeInt32(buf, pend, nTime);
}
- return SendRTMP(r, &packet, false);
+ return RTMP_SendPacket(r, &packet, false);
}
static void
@@ -1780,8 +1822,8 @@ EncodeInt32LE(char *output, int nVal)
return 4;
}
-static bool
-ReadPacket(RTMP * r, RTMPPacket * packet)
+bool
+RTMP_ReadPacket(RTMP * r, RTMPPacket * packet)
{
char type;
if (ReadN(r, &type, 1) == 0)
@@ -1916,46 +1958,6 @@ ReadPacket(RTMP * r, RTMPPacket * packet
return true;
}
-static int
-EncodeString(char *output, const AVal * strName, const AVal * strValue)
-{
- char *buf = output;
- buf += AMF_EncodeInt16(output, strName->av_len);
-
- memcpy(buf, strName->av_val, strName->av_len);
- buf += strName->av_len;
-
- buf += AMF_EncodeString(buf, strValue);
- return buf - output;
-}
-
-static int
-EncodeNumber(char *output, const AVal * strName, double dVal)
-{
- char *buf = output;
- buf += AMF_EncodeInt16(output, strName->av_len);
-
- memcpy(buf, strName->av_val, strName->av_len);
- buf += strName->av_len;
-
- buf += AMF_EncodeNumber(buf, dVal);
- return buf - output;
-}
-
-static int
-EncodeBoolean(char *output, const AVal * strName, bool bVal)
-{
- char *buf = output;
- buf += AMF_EncodeInt16(output, strName->av_len);
-
- memcpy(buf, strName->av_val, strName->av_len);
- buf += strName->av_len;
-
- buf += AMF_EncodeBoolean(buf, bVal);
-
- return buf - output;
-}
-
#ifdef CRYPTO
#include "handshake.h"
#else
@@ -2085,8 +2087,8 @@ SHandShake(RTMP * r)
}
#endif
-static bool
-SendRTMP(RTMP * r, RTMPPacket * packet, bool queue)
+bool
+RTMP_SendPacket(RTMP * r, RTMPPacket * packet, bool queue)
{
const RTMPPacket *prevPacket = r->m_vecChannelsOut[packet->m_nChannel];
if (prevPacket && packet->m_headerType != RTMP_PACKET_SIZE_LARGE)
@@ -2114,11 +2116,11 @@ SendRTMP(RTMP * r, RTMPPacket * packet,
char *header = packet->m_body - nSize;
header[0] = (char) ((packet->m_headerType << 6) | packet->m_nChannel);
if (nSize > 1)
- AMF_EncodeInt24(header + 1, packet->m_nInfoField1);
+ AMF_EncodeInt24(header + 1, packet->m_body, packet->m_nInfoField1);
if (nSize > 4)
{
- AMF_EncodeInt24(header + 4, packet->m_nBodySize);
+ AMF_EncodeInt24(header + 4, packet->m_body, packet->m_nBodySize);
header[7] = packet->m_packetType;
}
Modified: trunk/rtmp.h
==============================================================================
--- trunk/rtmp.h Tue Dec 22 01:50:58 2009 (r106)
+++ trunk/rtmp.h Tue Dec 22 05:55:19 2009 (r107)
@@ -59,7 +59,7 @@
extern const char RTMPProtocolStringsLower[][7];
extern bool RTMP_ctrlC;
-int32_t RTMP_GetTime();
+uint32_t RTMP_GetTime();
#define RTMP_PACKET_TYPE_AUDIO 0x08
#define RTMP_PACKET_TYPE_VIDEO 0x09
@@ -184,6 +184,8 @@ void RTMP_SetupStream(RTMP *r, int proto
bool RTMP_Connect(RTMP *r);
bool RTMP_Serve(RTMP *r);
+bool RTMP_ReadPacket(RTMP * r, RTMPPacket * packet);
+bool RTMP_SendPacket(RTMP * r, RTMPPacket * packet, bool queue);
bool RTMP_IsConnected(RTMP *r);
bool RTMP_IsTimedout(RTMP *r);
double RTMP_GetDuration(RTMP *r);
Modified: trunk/rtmpdump.c
==============================================================================
--- trunk/rtmpdump.c Tue Dec 22 01:50:58 2009 (r106)
+++ trunk/rtmpdump.c Tue Dec 22 05:55:19 2009 (r107)
@@ -406,7 +406,7 @@ WriteStream(RTMP * rtmp, char **buf, //
break;
}
}
- char *ptr = *buf;
+ char *ptr = *buf, *pend = ptr+size+4;
uint32_t nTimeStamp = 0; // use to return timestamp of last processed packet
@@ -425,7 +425,7 @@ WriteStream(RTMP * rtmp, char **buf, //
*ptr = packet.m_packetType;
ptr++;
- ptr += AMF_EncodeInt24(ptr, nPacketLen);
+ ptr = AMF_EncodeInt24(ptr, pend, nPacketLen);
/*if(packet.m_packetType == 0x09) { // video
@@ -444,12 +444,12 @@ WriteStream(RTMP * rtmp, char **buf, //
Log(LOGDEBUG, "VIDEO: nTimeStamp: 0x%08X (%d)\n", nTimeStamp, nTimeStamp);
} */
- ptr += AMF_EncodeInt24(ptr, nTimeStamp);
+ ptr = AMF_EncodeInt24(ptr, pend, nTimeStamp);
*ptr = (char) ((nTimeStamp & 0xFF000000) >> 24);
ptr++;
// stream id
- ptr += AMF_EncodeInt24(ptr, 0);
+ ptr = AMF_EncodeInt24(ptr, pend, 0);
}
memcpy(ptr, packetBody, nPacketLen);
@@ -489,7 +489,7 @@ WriteStream(RTMP * rtmp, char **buf, //
// we have to append a last tagSize!
prevTagSize = dataSize + 11;
- AMF_EncodeInt32(ptr + pos + 11 + dataSize, prevTagSize);
+ AMF_EncodeInt32(ptr + pos + 11 + dataSize, pend, prevTagSize);
size += 4;
len += 4;
}
@@ -514,7 +514,7 @@ WriteStream(RTMP * rtmp, char **buf, //
#endif
prevTagSize = dataSize + 11;
- AMF_EncodeInt32(ptr + pos + 11 + dataSize, prevTagSize);
+ AMF_EncodeInt32(ptr + pos + 11 + dataSize, pend, prevTagSize);
}
}
@@ -525,7 +525,7 @@ WriteStream(RTMP * rtmp, char **buf, //
if (packet.m_packetType != 0x16)
{ // FLV tag packets contain their own prevTagSize
- AMF_EncodeInt32(ptr, prevTagSize);
+ AMF_EncodeInt32(ptr, pend, prevTagSize);
//ptr += 4;
}
@@ -569,7 +569,7 @@ OpenResumeFile(const char *flvFile, // f
if (*size > 0)
{
- // verify FLV format and read header
+ // verify FLV format and read header
uint32_t prevTagSize = 0;
// check we've got a valid FLV file to continue!
@@ -704,7 +704,7 @@ GetLastKeyframe(FILE * file, // output f
Log(LOGDEBUG, "bAudioOnly: %d, size: %llu", bAudioOnly,
(unsigned long long) size);
- // ok, we have to get the timestamp of the last keyframe (only keyframes are seekable) / last audio frame (audio only streams)
+ // ok, we have to get the timestamp of the last keyframe (only keyframes are seekable) / last audio frame (audio only streams)
//if(!bAudioOnly) // we have to handle video/video+audio different since we have non-seekable frames
//{
@@ -798,7 +798,7 @@ GetLastKeyframe(FILE * file, // output f
*dSeek = AMF_DecodeInt24(buffer + 4); // set seek position to keyframe tmestamp
*dSeek |= (buffer[7] << 24);
- //}
+ //}
//else // handle audio only, we can seek anywhere we'd like
//{
//}
@@ -1521,7 +1521,7 @@ main(int argc, char **argv)
off_t size = 0;
- // ok, we have to get the timestamp of the last keyframe (only keyframes are seekable) / last audio frame (audio only streams)
+ // ok, we have to get the timestamp of the last keyframe (only keyframes are seekable) / last audio frame (audio only streams)
if (bResume)
{
nStatus =
Modified: trunk/streams.c
==============================================================================
--- trunk/streams.c Tue Dec 22 01:50:58 2009 (r106)
+++ trunk/streams.c Tue Dec 22 05:55:19 2009 (r107)
@@ -262,7 +262,7 @@ WriteStream(RTMP * rtmp, char **buf, //
break;
}
}
- char *ptr = *buf;
+ char *ptr = *buf, *pend = ptr + size+4;
// audio (0x08), video (0x09) or metadata (0x12) packets :
// construct 11 byte header then add rtmp packet's data
@@ -275,15 +275,14 @@ WriteStream(RTMP * rtmp, char **buf, //
(*nTimeStamp) = packet.m_nTimeStamp;
prevTagSize = 11 + nPacketLen;
- *ptr = packet.m_packetType;
- ptr++;
- ptr += AMF_EncodeInt24(ptr, nPacketLen);
- ptr += AMF_EncodeInt24(ptr, *nTimeStamp);
+ *ptr++ = packet.m_packetType;
+ ptr = AMF_EncodeInt24(ptr, pend, nPacketLen);
+ ptr = AMF_EncodeInt24(ptr, pend, *nTimeStamp);
*ptr = (char) (((*nTimeStamp) & 0xFF000000) >> 24);
ptr++;
// stream id
- ptr += AMF_EncodeInt24(ptr, 0);
+ ptr = AMF_EncodeInt24(ptr, pend, 0);
}
memcpy(ptr, packetBody, nPacketLen);
@@ -317,7 +316,7 @@ WriteStream(RTMP * rtmp, char **buf, //
// we have to append a last tagSize!
prevTagSize = dataSize + 11;
- AMF_EncodeInt32(ptr + pos + 11 + dataSize, prevTagSize);
+ AMF_EncodeInt32(ptr + pos + 11 + dataSize, pend, prevTagSize);
size += 4;
len += 4;
}
@@ -342,7 +341,7 @@ WriteStream(RTMP * rtmp, char **buf, //
#endif
prevTagSize = dataSize + 11;
- AMF_EncodeInt32(ptr + pos + 11 + dataSize, prevTagSize);
+ AMF_EncodeInt32(ptr + pos + 11 + dataSize, pend, prevTagSize);
}
}
@@ -353,7 +352,7 @@ WriteStream(RTMP * rtmp, char **buf, //
if (packet.m_packetType != 0x16)
{ // FLV tag packets contain their own prevTagSize
- AMF_EncodeInt32(ptr, prevTagSize);
+ AMF_EncodeInt32(ptr, pend, prevTagSize);
//ptr += 4;
}
@@ -469,7 +468,7 @@ void processTCPrequest(STREAMING_SERVER
)
{
char buf[512] = { 0 }; // answer buffer
- char header[2048] = { 0 }; // request header
+ char header[2048] = { 0 }; // request header
char *filename = NULL; // GET request: file name //512 not enuf
char *buffer = NULL; // stream buffer
char *ptr = NULL; // header pointer
@@ -602,7 +601,7 @@ void processTCPrequest(STREAMING_SERVER
__FUNCTION__);
}
- // do necessary checks right here to make sure the combined request of default values and GET parameters is correct
+ // do necessary checks right here to make sure the combined request of default values and GET parameters is correct
if (req.hostname == 0)
{
Log(LOGERROR,
@@ -699,7 +698,7 @@ void processTCPrequest(STREAMING_SERVER
{
Log(LOGERROR, "%s, sending failed, error: %d", __FUNCTION__,
GetSockError());
- goto cleanup; // we are in STREAMING_IN_PROGRESS, so we'll go to STREAMING_ACCEPTING
+ goto cleanup; // we are in STREAMING_IN_PROGRESS, so we'll go to STREAMING_ACCEPTING
}
size += nRead;
@@ -724,7 +723,7 @@ void processTCPrequest(STREAMING_SERVER
{
Log(LOGERROR, "%s, sending failed, error: %d", __FUNCTION__,
GetSockError());
- goto cleanup; // we are in STREAMING_IN_PROGRESS, so we'll go to STREAMING_ACCEPTING
+ goto cleanup; // we are in STREAMING_IN_PROGRESS, so we'll go to STREAMING_ACCEPTING
}
size += nRead;
@@ -902,7 +901,7 @@ sigIntHandler(int sig)
}
// this will parse RTMP related options as needed
-// excludes the following options: h, d, g
+// excludes the following options: h, d, g
// Return values: true (option parsing ok)
// false (option not parsed/invalid)
More information about the rtmpdump
mailing list