mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2026-01-10 06:41:11 +00:00
Added TCP fallback
Support for Windows Phone Silverlight Various fixes
This commit is contained in:
@@ -71,12 +71,19 @@ void tgvoip_openssl_sha256(uint8_t* msg, size_t len, uint8_t* output){
|
||||
SHA256(msg, len, output);
|
||||
}
|
||||
|
||||
void tgvoip_openssl_aes_ctr_encrypt(uint8_t* inout, size_t length, uint8_t* key, uint8_t* iv, uint8_t* ecount, uint32_t* num){
|
||||
AES_KEY akey;
|
||||
AES_set_encrypt_key(key, 32*8, &akey);
|
||||
AES_ctr128_encrypt(inout, inout, length, &akey, iv, ecount, num);
|
||||
}
|
||||
|
||||
voip_crypto_functions_t VoIPController::crypto={
|
||||
tgvoip_openssl_rand_bytes,
|
||||
tgvoip_openssl_sha1,
|
||||
tgvoip_openssl_sha256,
|
||||
tgvoip_openssl_aes_ige_encrypt,
|
||||
tgvoip_openssl_aes_ige_decrypt
|
||||
tgvoip_openssl_aes_ige_decrypt,
|
||||
tgvoip_openssl_aes_ctr_encrypt
|
||||
|
||||
};
|
||||
#else
|
||||
@@ -146,6 +153,9 @@ VoIPController::VoIPController() : activeNetItfName(""), currentAudioInput("defa
|
||||
receivedInitAck=false;
|
||||
peerPreferredRelay=NULL;
|
||||
statsDump=NULL;
|
||||
useTCP=false;
|
||||
didAddTcpRelays=false;
|
||||
enableTcpAt=0;
|
||||
|
||||
socket=NetworkSocket::Create();
|
||||
|
||||
@@ -287,8 +297,14 @@ void VoIPController::SetRemoteEndpoints(std::vector<Endpoint> endpoints, bool al
|
||||
size_t i;
|
||||
lock_mutex(endpointsMutex);
|
||||
this->endpoints.clear();
|
||||
didAddTcpRelays=false;
|
||||
useTCP=true;
|
||||
for(std::vector<Endpoint>::iterator itrtr=endpoints.begin();itrtr!=endpoints.end();++itrtr){
|
||||
this->endpoints.push_back(new Endpoint(*itrtr));
|
||||
if(itrtr->type==EP_TYPE_TCP_RELAY)
|
||||
didAddTcpRelays=true;
|
||||
if(itrtr->type==EP_TYPE_UDP_RELAY)
|
||||
useTCP=false;
|
||||
}
|
||||
unlock_mutex(endpointsMutex);
|
||||
currentEndpoint=this->endpoints[0];
|
||||
@@ -316,7 +332,7 @@ void* VoIPController::StartTickThread(void* controller){
|
||||
void VoIPController::Start(){
|
||||
int res;
|
||||
LOGW("Starting voip controller");
|
||||
int32_t cfgFrameSize=ServerConfig::GetSharedInstance()->GetInt("audio_frame_size", 60);
|
||||
int32_t cfgFrameSize=60; //ServerConfig::GetSharedInstance()->GetInt("audio_frame_size", 60);
|
||||
if(cfgFrameSize==20 || cfgFrameSize==40 || cfgFrameSize==60)
|
||||
outgoingStreams[0]->frameDuration=(uint16_t) cfgFrameSize;
|
||||
socket->Open();
|
||||
@@ -402,6 +418,7 @@ void VoIPController::HandleAudioInput(unsigned char *data, size_t len){
|
||||
void VoIPController::Connect(){
|
||||
assert(state!=STATE_WAIT_INIT_ACK);
|
||||
connectionInitTime=GetCurrentTime();
|
||||
enableTcpAt=connectionInitTime+5;
|
||||
SendInit();
|
||||
}
|
||||
|
||||
@@ -537,6 +554,8 @@ void VoIPController::SendInit(){
|
||||
out->WriteByte(0); // video codecs count
|
||||
lock_mutex(endpointsMutex);
|
||||
for(std::vector<Endpoint*>::iterator itr=endpoints.begin();itr!=endpoints.end();++itr){
|
||||
if((*itr)->type==EP_TYPE_TCP_RELAY && !useTCP)
|
||||
continue;
|
||||
SendPacket(out->GetBuffer(), out->GetLength(), *itr);
|
||||
}
|
||||
unlock_mutex(endpointsMutex);
|
||||
@@ -574,8 +593,10 @@ void VoIPController::RunRecvThread(){
|
||||
lock_mutex(endpointsMutex);
|
||||
for(std::vector<Endpoint*>::iterator itrtr=endpoints.begin();itrtr!=endpoints.end();++itrtr){
|
||||
if((*itrtr)->address==*src4 && (*itrtr)->port==packet.port){
|
||||
srcEndpoint=*itrtr;
|
||||
break;
|
||||
if(((*itrtr)->type!=EP_TYPE_TCP_RELAY && packet.protocol==PROTO_UDP) || ((*itrtr)->type==EP_TYPE_TCP_RELAY && packet.protocol==PROTO_TCP)){
|
||||
srcEndpoint=*itrtr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
unlock_mutex(endpointsMutex);
|
||||
@@ -595,7 +616,7 @@ void VoIPController::RunRecvThread(){
|
||||
stats.bytesRecvdWifi+=(uint64_t)len;
|
||||
BufferInputStream in(buffer, (size_t)len);
|
||||
try{
|
||||
if(memcmp(buffer, srcEndpoint->type==EP_TYPE_UDP_RELAY ? srcEndpoint->peerTag : callID, 16)!=0){
|
||||
if(memcmp(buffer, srcEndpoint->type==EP_TYPE_UDP_RELAY || srcEndpoint->type==EP_TYPE_TCP_RELAY ? srcEndpoint->peerTag : callID, 16)!=0){
|
||||
LOGW("Received packet has wrong peerTag");
|
||||
|
||||
continue;
|
||||
@@ -859,7 +880,7 @@ simpleAudioBlock random_id:long random_bytes:string raw_data:string = DecryptedA
|
||||
if(!receivedInit){
|
||||
receivedInit=true;
|
||||
currentEndpoint=srcEndpoint;
|
||||
if(srcEndpoint->type==EP_TYPE_UDP_RELAY)
|
||||
if(srcEndpoint->type==EP_TYPE_UDP_RELAY || (useTCP && srcEndpoint->type==EP_TYPE_TCP_RELAY))
|
||||
preferredRelay=srcEndpoint;
|
||||
LogDebugInfo();
|
||||
}
|
||||
@@ -1131,7 +1152,7 @@ simpleAudioBlock random_id:long random_bytes:string raw_data:string = DecryptedA
|
||||
endpoints.push_back(new Endpoint(0, peerPort, v4addr, v6addr, EP_TYPE_UDP_P2P_LAN, peerTag));
|
||||
unlock_mutex(endpointsMutex);
|
||||
}
|
||||
if(type==PKT_NETWORK_CHANGED){
|
||||
if(type==PKT_NETWORK_CHANGED && currentEndpoint->type!=EP_TYPE_UDP_RELAY && currentEndpoint->type!=EP_TYPE_TCP_RELAY){
|
||||
currentEndpoint=preferredRelay;
|
||||
if(allowP2p)
|
||||
SendPublicEndpointsRequest();
|
||||
@@ -1211,6 +1232,7 @@ void VoIPController::RunTickThread(){
|
||||
Sleep(100);
|
||||
#endif
|
||||
tickCount++;
|
||||
double time=GetCurrentTime();
|
||||
if(tickCount%5==0 && state==STATE_ESTABLISHED){
|
||||
memmove(&rttHistory[1], rttHistory, 31*sizeof(double));
|
||||
rttHistory[0]=GetAverageRTT();
|
||||
@@ -1244,6 +1266,26 @@ void VoIPController::RunTickThread(){
|
||||
|
||||
conctl->Tick();
|
||||
|
||||
if(!useTCP && ((state==STATE_WAIT_INIT_ACK && tickCount>=50) || (state==STATE_ESTABLISHED && time-lastRecvPacketTime>=5.0))){
|
||||
useTCP=true;
|
||||
if(!didAddTcpRelays){
|
||||
std::vector<Endpoint *> relays;
|
||||
for(std::vector<Endpoint *>::iterator itr=endpoints.begin(); itr!=endpoints.end(); ++itr){
|
||||
if((*itr)->type!=EP_TYPE_UDP_RELAY)
|
||||
continue;
|
||||
Endpoint *tcpRelay=new Endpoint(**itr);
|
||||
tcpRelay->type=EP_TYPE_TCP_RELAY;
|
||||
tcpRelay->averageRTT=0;
|
||||
tcpRelay->lastPingSeq=0;
|
||||
tcpRelay->lastPingTime=0;
|
||||
memset(tcpRelay->rtts, 0, sizeof(tcpRelay->rtts));
|
||||
relays.push_back(tcpRelay);
|
||||
}
|
||||
endpoints.insert(endpoints.end(), relays.begin(), relays.end());
|
||||
didAddTcpRelays=true;
|
||||
}
|
||||
}
|
||||
|
||||
if(state==STATE_ESTABLISHED){
|
||||
if((audioInput && !audioInput->IsInitialized()) || (audioOutput && !audioOutput->IsInitialized())){
|
||||
LOGE("Audio I/O failed");
|
||||
@@ -1372,6 +1414,8 @@ void VoIPController::RunTickThread(){
|
||||
double minPing=preferredRelay->averageRTT;
|
||||
for(std::vector<Endpoint*>::iterator e=endpoints.begin();e!=endpoints.end();++e){
|
||||
Endpoint* endpoint=*e;
|
||||
if(endpoint->type==EP_TYPE_TCP_RELAY && !useTCP)
|
||||
continue;
|
||||
if(GetCurrentTime()-endpoint->lastPingTime>=10){
|
||||
LOGV("Sending ping to %s", endpoint->address.ToString().c_str());
|
||||
BufferOutputStream pkt(32);
|
||||
@@ -1380,9 +1424,10 @@ void VoIPController::RunTickThread(){
|
||||
endpoint->lastPingSeq=seq;
|
||||
SendPacket(pkt.GetBuffer(), pkt.GetLength(), endpoint);
|
||||
}
|
||||
if(endpoint->type==EP_TYPE_UDP_RELAY){
|
||||
if(endpoint->averageRTT>0 && endpoint->averageRTT<minPing*relaySwitchThreshold){
|
||||
minPing=endpoint->averageRTT;
|
||||
if(endpoint->type==EP_TYPE_UDP_RELAY || (useTCP && endpoint->type==EP_TYPE_TCP_RELAY)){
|
||||
double k=endpoint->type==EP_TYPE_UDP_RELAY ? 1 : 2;
|
||||
if(endpoint->averageRTT>0 && endpoint->averageRTT*k<minPing*relaySwitchThreshold){
|
||||
minPing=endpoint->averageRTT*k;
|
||||
minPingRelay=endpoint;
|
||||
}
|
||||
}
|
||||
@@ -1390,7 +1435,7 @@ void VoIPController::RunTickThread(){
|
||||
if(minPingRelay!=preferredRelay){
|
||||
preferredRelay=minPingRelay;
|
||||
LOGV("set preferred relay to %s", preferredRelay->address.ToString().c_str());
|
||||
if(currentEndpoint->type==EP_TYPE_UDP_RELAY)
|
||||
if(currentEndpoint->type==EP_TYPE_UDP_RELAY || currentEndpoint->type==EP_TYPE_TCP_RELAY)
|
||||
currentEndpoint=preferredRelay;
|
||||
LogDebugInfo();
|
||||
/*BufferOutputStream pkt(32);
|
||||
@@ -1427,7 +1472,7 @@ void VoIPController::RunTickThread(){
|
||||
|
||||
if(state==STATE_ESTABLISHED){
|
||||
if(GetCurrentTime()-lastRecvPacketTime>=config.recv_timeout){
|
||||
if(currentEndpoint && currentEndpoint->type!=EP_TYPE_UDP_RELAY){
|
||||
if(currentEndpoint && currentEndpoint->type!=EP_TYPE_UDP_RELAY && currentEndpoint->type!=EP_TYPE_TCP_RELAY){
|
||||
LOGW("Packet receive timeout, switching to relay");
|
||||
currentEndpoint=preferredRelay;
|
||||
for(std::vector<Endpoint*>::iterator itrtr=endpoints.begin();itrtr!=endpoints.end();++itrtr){
|
||||
@@ -1498,11 +1543,13 @@ Endpoint& VoIPController::GetRemoteEndpoint(){
|
||||
void VoIPController::SendPacket(unsigned char *data, size_t len, Endpoint* ep){
|
||||
if(stopping)
|
||||
return;
|
||||
if(ep->type==EP_TYPE_TCP_RELAY && !useTCP)
|
||||
return;
|
||||
//dst.sin_addr=ep->address;
|
||||
//dst.sin_port=htons(ep->port);
|
||||
//dst.sin_family=AF_INET;
|
||||
BufferOutputStream out(len+128);
|
||||
if(ep->type==EP_TYPE_UDP_RELAY)
|
||||
if(ep->type==EP_TYPE_UDP_RELAY || ep->type==EP_TYPE_TCP_RELAY)
|
||||
out.WriteBytes((unsigned char*)ep->peerTag, 16);
|
||||
else
|
||||
out.WriteBytes(callID, 16);
|
||||
@@ -1537,6 +1584,7 @@ void VoIPController::SendPacket(unsigned char *data, size_t len, Endpoint* ep){
|
||||
pkt.port=ep->port;
|
||||
pkt.length=out.GetLength();
|
||||
pkt.data=out.GetBuffer();
|
||||
pkt.protocol=ep->type==EP_TYPE_TCP_RELAY ? PROTO_TCP : PROTO_UDP;
|
||||
socket->Send(&pkt);
|
||||
}
|
||||
|
||||
@@ -1554,13 +1602,21 @@ void VoIPController::SetNetworkType(int type){
|
||||
if(isFirstChange)
|
||||
return;
|
||||
if(currentEndpoint && currentEndpoint->type!=EP_TYPE_UDP_RELAY){
|
||||
currentEndpoint=preferredRelay;
|
||||
if(preferredRelay->type==EP_TYPE_UDP_RELAY)
|
||||
currentEndpoint=preferredRelay;
|
||||
for(std::vector<Endpoint*>::iterator itr=endpoints.begin();itr!=endpoints.end();){
|
||||
Endpoint* endpoint=*itr;
|
||||
if(endpoint->type==EP_TYPE_UDP_P2P_INET){
|
||||
if(endpoint->type==EP_TYPE_UDP_RELAY && useTCP){
|
||||
useTCP=false;
|
||||
if(preferredRelay->type==EP_TYPE_TCP_RELAY){
|
||||
preferredRelay=endpoint;
|
||||
currentEndpoint=endpoint;
|
||||
}
|
||||
}
|
||||
//if(endpoint->type==EP_TYPE_UDP_P2P_INET){
|
||||
endpoint->averageRTT=0;
|
||||
memset(endpoint->rtts, 0, sizeof(endpoint->rtts));
|
||||
}
|
||||
//}
|
||||
if(endpoint->type==EP_TYPE_UDP_P2P_LAN){
|
||||
delete endpoint;
|
||||
itr=endpoints.erase(itr);
|
||||
@@ -1987,6 +2043,9 @@ void VoIPController::LogDebugInfo(){
|
||||
case EP_TYPE_UDP_P2P_LAN:
|
||||
typeStr="udp_p2p_lan";
|
||||
break;
|
||||
case EP_TYPE_TCP_RELAY:
|
||||
typeStr="tcp_relay";
|
||||
break;
|
||||
}
|
||||
snprintf(buffer, 1024, "{\"address\":\"%s\",\"port\":%u,\"type\":\"%s\",\"rtt\":%u%s%s}", e->address.ToString().c_str(), e->port, typeStr, (unsigned int)round(e->averageRTT*1000), currentEndpoint==&*e ? ",\"in_use\":true" : "", preferredRelay==&*e ? ",\"preferred\":true" : "");
|
||||
json+=buffer;
|
||||
|
||||
Reference in New Issue
Block a user