Nagram/TMessagesProj/jni/tgnet/ConnectionsManager.h

252 lines
10 KiB
C
Raw Normal View History

2015-09-24 20:52:02 +00:00
/*
2018-07-30 02:07:02 +00:00
* This is the source code of tgnet library v. 1.1
2015-09-24 20:52:02 +00:00
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
2018-07-30 02:07:02 +00:00
* Copyright Nikolai Kudashov, 2015-2018.
2015-09-24 20:52:02 +00:00
*/
#ifndef CONNECTIONSMANAGER_H
#define CONNECTIONSMANAGER_H
#include <pthread.h>
#include <queue>
#include <functional>
#include <sys/epoll.h>
#include <map>
2015-11-26 21:04:02 +00:00
#include <atomic>
#include <memory>
2015-09-24 20:52:02 +00:00
#include "Defines.h"
#ifdef ANDROID
#include <jni.h>
#endif
class NativeByteBuffer;
class Connection;
class Datacenter;
class Request;
class DatacenterHandshake;
class TLObject;
class ConnectionSocket;
class TL_auth_exportedAuthorization;
class ByteArray;
class TL_config;
class EventObject;
class Config;
2018-07-30 02:07:02 +00:00
class ProxyCheckInfo;
2015-09-24 20:52:02 +00:00
class ConnectionsManager {
public:
2018-07-30 02:07:02 +00:00
ConnectionsManager(int32_t instance);
2015-09-24 20:52:02 +00:00
~ConnectionsManager();
2018-07-30 02:07:02 +00:00
static ConnectionsManager &getInstance(int32_t instanceNum);
2015-09-24 20:52:02 +00:00
int64_t getCurrentTimeMillis();
2017-03-30 23:58:05 +00:00
int64_t getCurrentTimeMonotonicMillis();
2015-09-24 20:52:02 +00:00
int32_t getCurrentTime();
2017-07-08 16:32:04 +00:00
bool isTestBackend();
2015-09-24 20:52:02 +00:00
int32_t getTimeDifference();
int32_t sendRequest(TLObject *object, onCompleteFunc onComplete, onQuickAckFunc onQuickAck, uint32_t flags, uint32_t datacenterId, ConnectionType connetionType, bool immediate);
2018-07-30 02:07:02 +00:00
int32_t sendRequest(TLObject *object, onCompleteFunc onComplete, onQuickAckFunc onQuickAck, uint32_t flags, uint32_t datacenterId, ConnectionType connetionType, bool immediate, int32_t requestToken);
2015-09-24 20:52:02 +00:00
void cancelRequest(int32_t token, bool notifyServer);
2018-07-30 02:07:02 +00:00
void cleanUp(bool resetKeys);
2015-09-24 20:52:02 +00:00
void cancelRequestsForGuid(int32_t guid);
void bindRequestToGuid(int32_t requestToken, int32_t guid);
void applyDatacenterAddress(uint32_t datacenterId, std::string ipAddress, uint32_t port);
void setDelegate(ConnectiosManagerDelegate *connectiosManagerDelegate);
ConnectionState getConnectionState();
void setUserId(int32_t userId);
void switchBackend();
void resumeNetwork(bool partial);
void pauseNetwork();
2018-07-30 02:07:02 +00:00
void setNetworkAvailable(bool value, int32_t type, bool slow);
2015-09-24 20:52:02 +00:00
void setUseIpv6(bool value);
2019-07-18 13:01:39 +00:00
void init(uint32_t version, int32_t layer, int32_t apiId, std::string deviceModel, std::string systemVersion, std::string appVersion, std::string langCode, std::string systemLangCode, std::string configPath, std::string logPath, std::string regId, int32_t userId, bool isPaused, bool enablePushConnection, bool hasNetwork, int32_t networkType);
2018-07-30 02:07:02 +00:00
void setProxySettings(std::string address, uint16_t port, std::string username, std::string password, std::string secret);
2017-07-08 16:32:04 +00:00
void setLangCode(std::string langCode);
2019-07-18 13:01:39 +00:00
void setRegId(std::string regId);
2019-01-23 17:03:33 +00:00
void setSystemLangCode(std::string langCode);
2017-07-08 16:32:04 +00:00
void updateDcSettings(uint32_t datacenterId, bool workaround);
2016-04-22 13:49:00 +00:00
void setPushConnectionEnabled(bool value);
2018-07-30 02:07:02 +00:00
void applyDnsConfig(NativeByteBuffer *buffer, std::string phone);
2017-03-30 23:58:05 +00:00
void setMtProtoVersion(int version);
int32_t getMtProtoVersion();
2018-07-30 02:07:02 +00:00
int64_t checkProxy(std::string address, uint16_t port, std::string username, std::string password, std::string secret, onRequestTimeFunc requestTimeFunc, jobject ptr1);
2015-09-24 20:52:02 +00:00
#ifdef ANDROID
2017-07-08 16:32:04 +00:00
void sendRequest(TLObject *object, onCompleteFunc onComplete, onQuickAckFunc onQuickAck, onWriteToSocketFunc onWriteToSocket, uint32_t flags, uint32_t datacenterId, ConnectionType connetionType, bool immediate, int32_t requestToken, jobject ptr1, jobject ptr2, jobject ptr3);
2015-09-24 20:52:02 +00:00
static void useJavaVM(JavaVM *vm, bool useJavaByteBuffers);
#endif
private:
static void *ThreadProc(void *data);
void initDatacenters();
void loadConfig();
void saveConfig();
2017-07-08 16:32:04 +00:00
void saveConfigInternal(NativeByteBuffer *buffer);
2015-09-24 20:52:02 +00:00
void select();
void wakeup();
void processServerResponse(TLObject *message, int64_t messageId, int32_t messageSeqNo, int64_t messageSalt, Connection *connection, int64_t innerMsgId, int64_t containerMessageId);
void sendPing(Datacenter *datacenter, bool usePushConnection);
void sendMessagesToConnection(std::vector<std::unique_ptr<NetworkMessage>> &messages, Connection *connection, bool reportAck);
void sendMessagesToConnectionWithConfirmation(std::vector<std::unique_ptr<NetworkMessage>> &messages, Connection *connection, bool reportAck);
void requestSaltsForDatacenter(Datacenter *datacenter);
2018-07-30 02:07:02 +00:00
void clearRequestsForDatacenter(Datacenter *datacenter, HandshakeType type);
2015-09-24 20:52:02 +00:00
void registerForInternalPushUpdates();
void processRequestQueue(uint32_t connectionType, uint32_t datacenterId);
void moveToDatacenter(uint32_t datacenterId);
void authorizeOnMovingDatacenter();
void authorizedOnMovingDatacenter();
Datacenter *getDatacenterWithId(uint32_t datacenterId);
std::unique_ptr<TLObject> wrapInLayer(TLObject *object, Datacenter *datacenter, Request *baseRequest);
void removeRequestFromGuid(int32_t requestToken);
2018-07-30 02:07:02 +00:00
bool cancelRequestInternal(int32_t token, int64_t messageId, bool notifyServer, bool removeFromClass);
2015-09-24 20:52:02 +00:00
int callEvents(int64_t now);
2016-10-11 11:57:01 +00:00
int32_t sendRequestInternal(TLObject *object, onCompleteFunc onComplete, onQuickAckFunc onQuickAck, uint32_t flags, uint32_t datacenterId, ConnectionType connetionType, bool immediate);
2015-09-24 20:52:02 +00:00
void checkPendingTasks();
void scheduleTask(std::function<void()> task);
void scheduleEvent(EventObject *eventObject, uint32_t time);
void removeEvent(EventObject *eventObject);
2017-07-08 16:32:04 +00:00
void onConnectionClosed(Connection *connection, int reason);
2015-09-24 20:52:02 +00:00
void onConnectionConnected(Connection *connection);
void onConnectionQuickAckReceived(Connection *connection, int32_t ack);
void onConnectionDataReceived(Connection *connection, NativeByteBuffer *data, uint32_t length);
2019-01-23 17:03:33 +00:00
bool hasPendingRequestsForConnection(Connection *connection);
2015-09-24 20:52:02 +00:00
void attachConnection(ConnectionSocket *connection);
void detachConnection(ConnectionSocket *connection);
TLObject *TLdeserialize(TLObject *request, uint32_t bytes, NativeByteBuffer *data);
TLObject *getRequestWithMessageId(int64_t messageId);
2018-07-30 02:07:02 +00:00
void onDatacenterHandshakeComplete(Datacenter *datacenter, HandshakeType type, int32_t timeDiff);
2015-09-24 20:52:02 +00:00
void onDatacenterExportAuthorizationComplete(Datacenter *datacenter);
int64_t generateMessageId();
bool isIpv6Enabled();
bool isNetworkAvailable();
2019-07-18 13:01:39 +00:00
void scheduleCheckProxyInternal(ProxyCheckInfo *proxyCheckInfo);
2018-07-30 02:07:02 +00:00
void checkProxyInternal(ProxyCheckInfo *proxyCheckInfo);
int32_t instanceNum = 0;
2019-01-23 17:03:33 +00:00
uint32_t configVersion = 4;
2015-09-24 20:52:02 +00:00
Config *config = nullptr;
std::list<EventObject *> events;
std::map<uint32_t, Datacenter *> datacenters;
std::map<int32_t, std::vector<std::int32_t>> quickAckIdToRequestIds;
int32_t pingTime;
bool testBackend = false;
2018-07-30 02:07:02 +00:00
bool clientBlocked = true;
2019-01-23 17:03:33 +00:00
std::string lastInitSystemLangcode = "";
2018-07-30 02:07:02 +00:00
std::atomic<uint32_t> lastRequestToken{50000000};
2015-09-24 20:52:02 +00:00
uint32_t currentDatacenterId = 0;
uint32_t movingToDatacenterId = DEFAULT_DATACENTER_ID;
int64_t pushSessionId = 0;
int32_t currentPingTime = 0;
bool registeringForPush = false;
int64_t lastPushPingTime = 0;
2019-05-14 12:08:05 +00:00
int32_t nextPingTimeOffset = 60000 * 3;
2015-09-24 20:52:02 +00:00
bool sendingPushPing = false;
2019-01-23 17:03:33 +00:00
bool sendingPing = false;
2015-09-24 20:52:02 +00:00
bool updatingDcSettings = false;
2017-07-08 16:32:04 +00:00
bool updatingDcSettingsWorkaround = false;
int32_t disconnectTimeoutAmount = 0;
int32_t requestingSecondAddress = 0;
2015-09-24 20:52:02 +00:00
int32_t updatingDcStartTime = 0;
int32_t lastDcUpdateTime = 0;
2017-03-30 23:58:05 +00:00
int64_t lastPingTime = getCurrentTimeMonotonicMillis();
2015-09-24 20:52:02 +00:00
bool networkPaused = false;
2016-04-22 13:49:00 +00:00
int32_t nextSleepTimeout = CONNECTION_BACKGROUND_KEEP_TIME;
2015-09-24 20:52:02 +00:00
int64_t lastPauseTime = 0;
ConnectionState connectionState = ConnectionStateConnecting;
std::unique_ptr<ByteArray> movingAuthorization;
std::vector<int64_t> sessionsToDestroy;
int32_t lastDestroySessionRequestTime;
std::map<int32_t, std::vector<int32_t>> requestsByGuids;
std::map<int32_t, int32_t> guidsByRequests;
2017-12-08 17:35:59 +00:00
std::map<int64_t, int64_t> resendRequests;
2018-07-30 02:07:02 +00:00
Datacenter *deserializingDatacenter;
2015-09-24 20:52:02 +00:00
2017-07-08 16:32:04 +00:00
std::string proxyUser = "";
std::string proxyPassword = "";
std::string proxyAddress = "";
2018-07-30 02:07:02 +00:00
std::string proxySecret = "";
uint16_t proxyPort = 1080;
int32_t lastPingProxyId = 2000000;
std::vector<std::unique_ptr<ProxyCheckInfo>> proxyCheckQueue;
std::vector<std::unique_ptr<ProxyCheckInfo>> proxyActiveChecks;
2017-07-08 16:32:04 +00:00
2015-09-24 20:52:02 +00:00
pthread_t networkThread;
pthread_mutex_t mutex;
std::queue<std::function<void()>> pendingTasks;
struct epoll_event *epollEvents;
timespec timeSpec;
2017-03-30 23:58:05 +00:00
timespec timeSpecMonotonic;
2015-09-24 20:52:02 +00:00
int32_t timeDifference = 0;
int64_t lastOutgoingMessageId = 0;
bool networkAvailable = true;
2018-07-30 02:07:02 +00:00
bool networkSlow = false;
2015-09-24 20:52:02 +00:00
bool ipv6Enabled = false;
std::vector<ConnectionSocket *> activeConnections;
int epolFd;
2016-10-11 11:57:01 +00:00
int eventFd;
int *pipeFd;
2015-09-24 20:52:02 +00:00
NativeByteBuffer *networkBuffer;
requestsList requestsQueue;
requestsList runningRequests;
std::vector<uint32_t> requestingSaltsForDc;
int32_t lastPingId = 0;
2017-03-30 23:58:05 +00:00
int32_t currentNetworkType = NETWORK_TYPE_WIFI;
2015-09-24 20:52:02 +00:00
uint32_t currentVersion = 1;
int32_t currentLayer = 34;
int32_t currentApiId = 6;
std::string currentDeviceModel;
std::string currentSystemVersion;
std::string currentAppVersion;
std::string currentLangCode;
2019-07-18 13:01:39 +00:00
std::string currentRegId;
2017-07-08 16:32:04 +00:00
std::string currentSystemLangCode;
2015-09-24 20:52:02 +00:00
std::string currentConfigPath;
2015-10-29 17:10:07 +00:00
std::string currentLogPath;
2015-09-24 20:52:02 +00:00
int32_t currentUserId = 0;
bool registeredForInternalPush = false;
2016-04-22 13:49:00 +00:00
bool pushConnectionEnabled = true;
2017-03-30 23:58:05 +00:00
int32_t mtProtoVersion = 2;
2015-09-24 20:52:02 +00:00
2018-07-30 02:07:02 +00:00
std::map<uint32_t, std::vector<std::unique_ptr<NetworkMessage>>> genericMessagesToDatacenters;
std::map<uint32_t, std::vector<std::unique_ptr<NetworkMessage>>> genericMediaMessagesToDatacenters;
std::map<uint32_t, std::vector<std::unique_ptr<NetworkMessage>>> tempMessagesToDatacenters;
std::vector<uint32_t> unknownDatacenterIds;
std::vector<std::pair<Datacenter *, ConnectionType>> neededDatacenters;
std::map<uint32_t, uint32_t> downloadRunningRequestCount;
std::vector<Datacenter *> unauthorizedDatacenters;
NativeByteBuffer *sizeCalculator;
2015-09-24 20:52:02 +00:00
ConnectiosManagerDelegate *delegate;
friend class ConnectionSocket;
friend class ConnectionSession;
friend class Connection;
friend class Timer;
friend class Datacenter;
friend class TL_message;
friend class TL_rpc_result;
friend class Config;
2018-07-30 02:07:02 +00:00
friend class FileLog;
friend class Handshake;
2015-09-24 20:52:02 +00:00
};
#ifdef ANDROID
extern JavaVM *javaVm;
2018-07-30 02:07:02 +00:00
extern JNIEnv *jniEnv[MAX_ACCOUNT_COUNT];
2015-09-24 20:52:02 +00:00
extern jclass jclass_ByteBuffer;
extern jmethodID jclass_ByteBuffer_allocateDirect;
#endif
#endif