diff --git a/NetworkSocket.cpp b/NetworkSocket.cpp index 2396146..c32bd8f 100644 --- a/NetworkSocket.cpp +++ b/NetworkSocket.cpp @@ -288,9 +288,11 @@ void NetworkSocketTCPObfuscated::Receive(NetworkPacket *packet){ size_t packetLen=0; size_t offset=0; size_t len; - wrapped->Receive(&len1, 1); - /*if(len<=0) - goto failed;*/ + len=wrapped->Receive(&len1, 1); + if(len<=0){ + packet->length=0; + return; + } EncryptForTCPO2(&len1, 1, &recvState); if(len1<0x7F){ @@ -298,8 +300,10 @@ void NetworkSocketTCPObfuscated::Receive(NetworkPacket *packet){ }else{ unsigned char len2[3]; len=wrapped->Receive(len2, 3); - /*if(len<=0) - goto failed;*/ + if(len<=0){ + packet->length=0; + return; + } EncryptForTCPO2(len2, 3, &recvState); packetLen=((size_t)len2[0] | ((size_t)len2[1] << 8) | ((size_t)len2[2] << 16))*4; } @@ -312,8 +316,10 @@ void NetworkSocketTCPObfuscated::Receive(NetworkPacket *packet){ while(offsetReceive(packet->data+offset, packetLen-offset); - /*if(len<=0) - goto failed;*/ + if(len<=0){ + packet->length=0; + return; + } offset+=len; } EncryptForTCPO2(packet->data, packetLen, &recvState); diff --git a/VoIPController.cpp b/VoIPController.cpp index e361dcb..f78357a 100644 --- a/VoIPController.cpp +++ b/VoIPController.cpp @@ -432,6 +432,8 @@ void VoIPController::HandleAudioInput(unsigned char *data, size_t len, unsigned /*.endpoint=*/0, }; sendQueue->Put(p); + }else{ + LOGW("Out of outgoing packet buffers!"); } if(secondaryData && secondaryLen && shittyInternetMode){ Buffer ecBuf(secondaryLen); @@ -458,6 +460,8 @@ void VoIPController::HandleAudioInput(unsigned char *data, size_t len, unsigned 0 }; sendQueue->Put(p); + }else{ + LOGW("Out of outgoing packet buffers!"); } } @@ -723,7 +727,8 @@ void VoIPController::SendInit(){ }); } } - SetState(STATE_WAIT_INIT_ACK); + if(state==STATE_WAIT_INIT) + SetState(STATE_WAIT_INIT_ACK); messageThread.Post([this]{ if(state==STATE_WAIT_INIT_ACK){ SendInit(); @@ -802,16 +807,6 @@ void VoIPController::RunRecvThread(void* arg){ SetState(STATE_FAILED); return; } - } - - NetworkSocket* socket=NULL; - - if(find(readSockets.begin(), readSockets.end(), realUdpSocket)!=readSockets.end()){ - socket=udpSocket; - }else if(readSockets.size()>0){ - socket=readSockets[0]; - }else{ - LOGI("no sockets to read from"); MutexGuard m(endpointsMutex); for(vector::iterator itr=errorSockets.begin();itr!=errorSockets.end();++itr){ for(shared_ptr& e:endpoints){ @@ -820,68 +815,80 @@ void VoIPController::RunRecvThread(void* arg){ delete e->socket; e->socket=NULL; LOGI("Closing failed TCP socket for %s:%u", e->GetAddress().ToString().c_str(), e->port); - break; } } } continue; } - socket->Receive(&packet); - if(!packet.address){ - LOGE("Packet has null address. This shouldn't happen."); - continue; - } - size_t len=packet.length; - if(!len){ - LOGE("Packet has zero length."); - continue; - } - //LOGV("Received %d bytes from %s:%d at %.5lf", len, packet.address->ToString().c_str(), packet.port, GetCurrentTime()); - shared_ptr srcEndpoint; + //NetworkSocket* socket=NULL; - IPv4Address* src4=dynamic_cast(packet.address); - if(src4){ - MutexGuard m(endpointsMutex); - for(shared_ptr& e:endpoints){ - if(e->address==*src4 && e->port==packet.port){ - if((e->type!=Endpoint::TYPE_TCP_RELAY && packet.protocol==PROTO_UDP) || (e->type==Endpoint::TYPE_TCP_RELAY && packet.protocol==PROTO_TCP)){ - srcEndpoint=e; - break; - } - } - } + /*if(find(readSockets.begin(), readSockets.end(), realUdpSocket)!=readSockets.end()){ + socket=udpSocket; + }else if(readSockets.size()>0){ + socket=readSockets[0]; }else{ - IPv6Address* src6=dynamic_cast(packet.address); - if(src6){ + LOGI("no sockets to read from"); + continue; + }*/ + + for(NetworkSocket*& socket:readSockets){ + socket->Receive(&packet); + if(!packet.address){ + LOGE("Packet has null address. This shouldn't happen."); + continue; + } + size_t len=packet.length; + if(!len){ + LOGE("Packet has zero length."); + continue; + } + //LOGV("Received %d bytes from %s:%d at %.5lf", len, packet.address->ToString().c_str(), packet.port, GetCurrentTime()); + shared_ptr srcEndpoint; + + IPv4Address *src4=dynamic_cast(packet.address); + if(src4){ MutexGuard m(endpointsMutex); - for(shared_ptr& e:endpoints){ - if(e->v6address==*src6 && e->port==packet.port && e->address.IsEmpty()){ + for(shared_ptr &e:endpoints){ + if(e->address==*src4 && e->port==packet.port){ if((e->type!=Endpoint::TYPE_TCP_RELAY && packet.protocol==PROTO_UDP) || (e->type==Endpoint::TYPE_TCP_RELAY && packet.protocol==PROTO_TCP)){ srcEndpoint=e; break; } } } + }else{ + IPv6Address *src6=dynamic_cast(packet.address); + if(src6){ + MutexGuard m(endpointsMutex); + for(shared_ptr &e:endpoints){ + if(e->v6address==*src6 && e->port==packet.port && e->address.IsEmpty()){ + if((e->type!=Endpoint::TYPE_TCP_RELAY && packet.protocol==PROTO_UDP) || (e->type==Endpoint::TYPE_TCP_RELAY && packet.protocol==PROTO_TCP)){ + srcEndpoint=e; + break; + } + } + } + } } - } - if(!srcEndpoint){ - LOGW("Received a packet from unknown source %s:%u", packet.address->ToString().c_str(), packet.port); - continue; - } - if(len<=0){ - //LOGW("error receiving: %d / %s", errno, strerror(errno)); - continue; - } - if(IS_MOBILE_NETWORK(networkType)) - stats.bytesRecvdMobile+=(uint64_t)len; - else - stats.bytesRecvdWifi+=(uint64_t)len; - try{ - ProcessIncomingPacket(packet, srcEndpoint); - }catch(out_of_range x){ - LOGW("Error parsing packet: %s", x.what()); + if(!srcEndpoint){ + LOGW("Received a packet from unknown source %s:%u", packet.address->ToString().c_str(), packet.port); + continue; + } + if(len<=0){ + //LOGW("error receiving: %d / %s", errno, strerror(errno)); + continue; + } + if(IS_MOBILE_NETWORK(networkType)) + stats.bytesRecvdMobile+=(uint64_t) len; + else + stats.bytesRecvdWifi+=(uint64_t) len; + try{ + ProcessIncomingPacket(packet, srcEndpoint); + }catch(out_of_range x){ + LOGW("Error parsing packet: %s", x.what()); + } } } free(buffer); @@ -1315,68 +1322,68 @@ simpleAudioBlock random_id:long random_bytes:string raw_data:string = DecryptedA preferredRelay=srcEndpoint; } LogDebugInfo(); - } - peerVersion=(uint32_t) in.ReadInt32(); - LOGI("Peer version is %d", peerVersion); - uint32_t minVer=(uint32_t) in.ReadInt32(); - if(minVer>PROTOCOL_VERSION || peerVersionPROTOCOL_VERSION || peerVersion=2 ? 10 : 2)+(peerVersion>=2 ? 6 : 4)*outgoingStreams.size()); - - out.WriteInt32(PROTOCOL_VERSION); - out.WriteInt32(MIN_PROTOCOL_VERSION); - - out.WriteByte((unsigned char) outgoingStreams.size()); - for(vector>::iterator s=outgoingStreams.begin();s!=outgoingStreams.end();++s){ - out.WriteByte((*s)->id); - out.WriteByte((*s)->type); - if(peerVersion<5) - out.WriteByte((unsigned char) ((*s)->codec==CODEC_OPUS ? CODEC_OPUS_OLD : 0)); - else - out.WriteInt32((*s)->codec); - out.WriteInt16((*s)->frameDuration); - out.WriteByte((unsigned char) ((*s)->enabled ? 1 : 0)); + SetState(STATE_FAILED); + return; + } + uint32_t flags=(uint32_t) in.ReadInt32(); + if(flags & INIT_FLAG_DATA_SAVING_ENABLED){ + dataSavingRequestedByPeer=true; + UpdateDataSavingState(); + UpdateAudioBitrateLimit(); + } + if(flags & INIT_FLAG_GROUP_CALLS_SUPPORTED){ + peerCapabilities|=TGVOIP_PEER_CAP_GROUP_CALLS; + } + + unsigned int i; + unsigned int numSupportedAudioCodecs=in.ReadByte(); + for(i=0; i=2 ? 10 : 2)+(peerVersion>=2 ? 6 : 4)*outgoingStreams.size()); + + out.WriteInt32(PROTOCOL_VERSION); + out.WriteInt32(MIN_PROTOCOL_VERSION); + + out.WriteByte((unsigned char) outgoingStreams.size()); + for(vector>::iterator s=outgoingStreams.begin(); s!=outgoingStreams.end(); ++s){ + out.WriteByte((*s)->id); + out.WriteByte((*s)->type); + if(peerVersion<5) + out.WriteByte((unsigned char) ((*s)->codec==CODEC_OPUS ? CODEC_OPUS_OLD : 0)); + else + out.WriteInt32((*s)->codec); + out.WriteInt16((*s)->frameDuration); + out.WriteByte((unsigned char) ((*s)->enabled ? 1 : 0)); + } + sendQueue->Put(PendingOutgoingPacket{ + /*.seq=*/GenerateOutSeq(), + /*.type=*/PKT_INIT_ACK, + /*.len=*/out.GetLength(), + /*.data=*/buf, + /*.endpoint=*/0 + }); } - sendQueue->Put(PendingOutgoingPacket{ - /*.seq=*/GenerateOutSeq(), - /*.type=*/PKT_INIT_ACK, - /*.len=*/out.GetLength(), - /*.data=*/buf, - /*.endpoint=*/0 - }); } } if(type==PKT_INIT_ACK){ @@ -1467,8 +1474,15 @@ simpleAudioBlock random_id:long random_bytes:string raw_data:string = DecryptedA } } if(type==PKT_STREAM_DATA || type==PKT_STREAM_DATA_X2 || type==PKT_STREAM_DATA_X3){ - if(state!=STATE_ESTABLISHED && receivedInitAck) - SetState(STATE_ESTABLISHED); + if(!receivedFirstStreamPacket){ + receivedFirstStreamPacket=true; + if(state!=STATE_ESTABLISHED && receivedInitAck){ + messageThread.Post([this](){ + SetState(STATE_ESTABLISHED); + }, .5); + LOGW("First audio packet - setting state to ESTABLISHED"); + } + } int count; switch(type){ case PKT_STREAM_DATA_X2: @@ -2245,7 +2259,7 @@ string VoIPController::GetDebugString(){ type="UNKNOWN"; break; } - snprintf(buffer, sizeof(buffer), "%s:%u %dms %d [%s%s]\n", endpoint->address.IsEmpty() ? ("["+endpoint->v6address.ToString()+"]").c_str() : endpoint->address.ToString().c_str(), endpoint->port, (int)(endpoint->averageRTT*1000), endpoint->udpPongCount, type, currentEndpoint==endpoint ? ", IN_USE" : ""); + snprintf(buffer, sizeof(buffer), "%s:%u %dms %d 0x%lx [%s%s]\n", endpoint->address.IsEmpty() ? ("["+endpoint->v6address.ToString()+"]").c_str() : endpoint->address.ToString().c_str(), endpoint->port, (int)(endpoint->averageRTT*1000), endpoint->udpPongCount, (uint64_t)endpoint->id, type, currentEndpoint==endpoint ? ", IN_USE" : ""); r+=buffer; } if(shittyInternetMode){ @@ -2671,6 +2685,7 @@ void VoIPController::StartAudio(){ } void VoIPController::OnAudioOutputReady(){ + LOGI("Audio I/O ready"); shared_ptr& stm=incomingStreams[0]; outputAGC=new AutomaticGainControl(); outputAGC->SetPassThrough(!outputAGCEnabled); diff --git a/VoIPController.h b/VoIPController.h index a8a64f8..8f7148e 100644 --- a/VoIPController.h +++ b/VoIPController.h @@ -34,7 +34,7 @@ #include "PacketReassembler.h" #include "MessageThread.h" -#define LIBTGVOIP_VERSION "2.2" +#define LIBTGVOIP_VERSION "2.2.1" #ifdef _WIN32 #undef GetCurrentTime @@ -593,6 +593,7 @@ namespace tgvoip{ int publicEndpointsReqCount=0; MessageThread messageThread; bool wasEstablished=false; + bool receivedFirstStreamPacket=false; uint32_t initTimeoutID=MessageThread::INVALID_ID; uint32_t noStreamsNopID=MessageThread::INVALID_ID; diff --git a/os/posix/NetworkSocketPosix.cpp b/os/posix/NetworkSocketPosix.cpp index fb483eb..ef8d2cb 100644 --- a/os/posix/NetworkSocketPosix.cpp +++ b/os/posix/NetworkSocketPosix.cpp @@ -146,6 +146,10 @@ void NetworkSocketPosix::Send(NetworkPacket *packet){ } void NetworkSocketPosix::Receive(NetworkPacket *packet){ + if(failed){ + packet->length=0; + return; + } if(protocol==PROTO_UDP){ int addrLen=sizeof(sockaddr_in6); sockaddr_in6 srcAddr; @@ -177,6 +181,7 @@ void NetworkSocketPosix::Receive(NetworkPacket *packet){ if(res<=0){ LOGE("Error receiving from TCP socket: %d / %s", errno, strerror(errno)); failed=true; + packet->length=0; }else{ packet->length=(size_t)res; packet->address=tcpConnectedAddress;