Merge "RTP: Revise the workaround of private addresses and fix bugs." into gingerbread

This commit is contained in:
Chia-chi Yeh
2010-09-29 11:50:16 -07:00
committed by Android (Google) Code Review

View File

@@ -86,8 +86,6 @@ public:
void decode(int tick); void decode(int tick);
private: private:
bool isNatAddress(struct sockaddr_storage *addr);
enum { enum {
NORMAL = 0, NORMAL = 0,
SEND_ONLY = 1, SEND_ONLY = 1,
@@ -101,6 +99,7 @@ private:
AudioCodec *mCodec; AudioCodec *mCodec;
uint32_t mCodecMagic; uint32_t mCodecMagic;
uint32_t mDtmfMagic; uint32_t mDtmfMagic;
bool mFixRemote;
int mTick; int mTick;
int mSampleRate; int mSampleRate;
@@ -181,6 +180,20 @@ bool AudioStream::set(int mode, int socket, sockaddr_storage *remote,
if (codec) { if (codec) {
mRemote = *remote; mRemote = *remote;
mCodec = codec; mCodec = codec;
// Here we should never get an private address, but some buggy proxy
// servers do give us one. To solve this, we replace the address when
// the first time we successfully decode an incoming packet.
mFixRemote = false;
if (remote->ss_family == AF_INET) {
unsigned char *address =
(unsigned char *)&((sockaddr_in *)remote)->sin_addr;
if (address[0] == 10 ||
(address[0] == 172 && (address[1] >> 4) == 1) ||
(address[0] == 192 && address[1] == 168)) {
mFixRemote = true;
}
}
} }
LOGD("stream[%d] is configured as %s %dkHz %dms", mSocket, LOGD("stream[%d] is configured as %s %dkHz %dms", mSocket,
@@ -318,16 +331,6 @@ void AudioStream::encode(int tick, AudioStream *chain)
sizeof(mRemote)); sizeof(mRemote));
} }
bool AudioStream::isNatAddress(struct sockaddr_storage *addr) {
if (addr->ss_family != AF_INET) return false;
struct sockaddr_in *s4 = (struct sockaddr_in *)addr;
unsigned char *d = (unsigned char *) &s4->sin_addr;
if ((d[0] == 10)
|| ((d[0] == 172) && (d[1] & 0x10))
|| ((d[0] == 192) && (d[1] == 168))) return true;
return false;
}
void AudioStream::decode(int tick) void AudioStream::decode(int tick)
{ {
char c; char c;
@@ -375,21 +378,11 @@ void AudioStream::decode(int tick)
MSG_TRUNC | MSG_DONTWAIT) >> 1; MSG_TRUNC | MSG_DONTWAIT) >> 1;
} else { } else {
__attribute__((aligned(4))) uint8_t buffer[2048]; __attribute__((aligned(4))) uint8_t buffer[2048];
struct sockaddr_storage src_addr; sockaddr_storage remote;
socklen_t addrlen; socklen_t len = sizeof(remote);
length = recvfrom(mSocket, buffer, sizeof(buffer),
MSG_TRUNC|MSG_DONTWAIT, (sockaddr*)&src_addr, &addrlen);
// The following if clause is for fixing the target address if length = recvfrom(mSocket, buffer, sizeof(buffer),
// proxy server did not replace the NAT address with its media MSG_TRUNC | MSG_DONTWAIT, (sockaddr *)&remote, &len);
// port in SDP. Although it is proxy server's responsibility for
// replacing the connection address with correct one, we will change
// the target address as we detect the difference for now until we
// know the best way to get rid of this issue.
if ((memcmp((void*)&src_addr, (void*)&mRemote, addrlen) != 0) &&
isNatAddress(&mRemote)) {
memcpy((void*)&mRemote, (void*)&src_addr, addrlen);
}
// Do we need to check SSRC, sequence, and timestamp? They are not // Do we need to check SSRC, sequence, and timestamp? They are not
// reliable but at least they can be used to identify duplicates? // reliable but at least they can be used to identify duplicates?
@@ -409,8 +402,12 @@ void AudioStream::decode(int tick)
if (length >= 0) { if (length >= 0) {
length = mCodec->decode(samples, &buffer[offset], length); length = mCodec->decode(samples, &buffer[offset], length);
} }
if (length > 0 && mFixRemote) {
mRemote = remote;
mFixRemote = false;
}
} }
if (length != mSampleCount) { if (length <= 0) {
LOGD("stream[%d] decoder error", mSocket); LOGD("stream[%d] decoder error", mSocket);
return; return;
} }