Sfoglia il codice sorgente

Reserved Net Operations

New reserved Net Operations to do nothing if not implemented
Also, clean some code and corrected some bugs
PascalCoin 7 anni fa
parent
commit
d5cda57ec7
1 ha cambiato i file con 61 aggiunte e 28 eliminazioni
  1. 61 28
      src/core/UNetProtocol.pas

+ 61 - 28
src/core/UNetProtocol.pas

@@ -47,6 +47,10 @@ Const
   CT_NetOp_GetPendingOperations = $0030; // Obtain pending operations
   CT_NetOp_GetAccount           = $0031; // Obtain account info
 
+  CT_NetOp_Reserved_Start       = $1000; // This will provide a reserved area
+  CT_NetOp_Reserved_End         = $1FFF; // End of reserved area
+  CT_NetOp_ERRORCODE_NOT_IMPLEMENTED = $00FF;// This will be error code returned when using Reserved area and Op is not implemented
+
 
   CT_NetError_InvalidProtocolVersion = $0001;
   CT_NetError_IPBlackListed = $0002;
@@ -206,7 +210,7 @@ Type
   TThreadCheckConnections = Class(TPCThread)
   private
     FNetData : TNetData;
-    FLastCheckTS : Cardinal;
+    FLastCheckTS : TTickCount;
   protected
     procedure BCExecute; override;
   public
@@ -217,7 +221,6 @@ Type
   private
     FTimesList : TPCThreadList;
     FTimeOffset : Integer;
-    FLock : TCriticalSection;
     FTotalCounter : Integer;
     Function IndexOfClientIp(list : TList; const clientIp : AnsiString) : Integer;
     Procedure UpdateMedian(list : TList);
@@ -232,6 +235,8 @@ Type
     function GetMaxAllowedTimestampForNewBlock : Cardinal;
   end;
 
+  TProcessReservedAreaMessage = procedure (netData : TNetData; senderConnection : TNetConnection; const HeaderData : TNetHeaderData; receivedData : TStream; responseData : TStream) of object;
+
   TNetData = Class(TComponent)
   private
     FMaxNodeServersAddressesBuffer: Integer;
@@ -240,6 +245,7 @@ Type
     FNetConnections : TPCThreadList;
     FNodeServersAddresses : TOrderedServerAddressListTS;
     FLastRequestId : Cardinal;
+    FOnProcessReservedAreaMessage: TProcessReservedAreaMessage;
     FRegisteredRequests : TPCThreadList;
     FIsDiscoveringServers : Boolean;
     FIsGettingNewBlockChainFromClient : Boolean;
@@ -262,6 +268,8 @@ Type
     procedure SetNetConnectionsActive(const Value: Boolean);  protected
     procedure Notification(AComponent: TComponent; Operation: TOperation); override;
     Procedure DiscoverServersTerminated(Sender : TObject);
+  protected
+    procedure DoProcessReservedAreaMessage(senderConnection : TNetConnection; const headerData : TNetHeaderData; receivedData : TStream; responseData : TStream); virtual;
   public
     Class function HeaderDataToText(const HeaderData : TNetHeaderData) : AnsiString;
     Class function ExtractHeaderInfo(buffer : TStream; var HeaderData : TNetHeaderData; DataBuffer : TStream; var IsValidHeaderButNeedMoreData : Boolean) : Boolean;
@@ -317,6 +325,7 @@ Type
     Property NetConnectionsActive : Boolean read FNetConnectionsActive write SetNetConnectionsActive;
     Property NetworkAdjustedTime : TNetworkAdjustedTime read FNetworkAdjustedTime;
     Property MaxNodeServersAddressesBuffer : Integer read FMaxNodeServersAddressesBuffer write SetMaxNodeServersAddressesBuffer;
+    Property OnProcessReservedAreaMessage : TProcessReservedAreaMessage read FOnProcessReservedAreaMessage write FOnProcessReservedAreaMessage;
   End;
 
   { TNetConnection }
@@ -327,8 +336,8 @@ Type
     FTcpIpClient : TNetTcpIpClient;
     FRemoteOperationBlock : TOperationBlock;
     FRemoteAccumulatedWork : UInt64;
-    FLastDataReceivedTS : Cardinal;
-    FLastDataSendedTS : Cardinal;
+    FLastDataReceivedTS : TTickCount;
+    FLastDataSendedTS : TTickCount;
     FClientBufferRead : TStream;
     FNetLock : TPCCriticalSection;
     FIsWaitingForResponse : Boolean;
@@ -443,6 +452,7 @@ Type
   TThreadGetNewBlockChainFromClient = Class(TPCThread)
   protected
     procedure BCExecute; override;
+  public
     Constructor Create;
   End;
 
@@ -487,11 +497,9 @@ begin
 end;
 
 procedure TOrderedServerAddressListTS.CleanNodeServersList;
-var i,j : Integer;
+var i : Integer;
   nsa : TNodeServerAddress;
   currunixtimestamp : Cardinal;
-  l : TList;
-  Aux : TNodeServerAddressArray;
 begin
   currunixtimestamp := UnivDateTimeToUnix(DateTime2UnivDateTime(now));
   FCritical.Acquire;
@@ -1111,6 +1119,8 @@ end;
 
 constructor TNetData.Create(AOwner: TComponent);
 begin
+  inherited Create(AOwner);  // XXXXXXXXXXXXX BUG
+  FOnProcessReservedAreaMessage:=Nil;
   TLog.NewLog(ltInfo,ClassName,'TNetData.Create');
   FMaxConnections := CT_MaxClientsConnected;
   FNetConnectionsActive := true;
@@ -1291,6 +1301,13 @@ begin
   TThreadGetNewBlockChainFromClient.Create;
 end;
 
+procedure TNetData.DoProcessReservedAreaMessage(senderConnection : TNetConnection; const headerData: TNetHeaderData; receivedData: TStream; responseData: TStream);
+begin
+  If Assigned(FOnProcessReservedAreaMessage) then begin
+    FOnProcessReservedAreaMessage(Self,senderConnection,headerData,receivedData,responseData);
+  end;
+end;
+
 class function TNetData.ExtractHeaderInfo(buffer : TStream; var HeaderData : TNetHeaderData; DataBuffer : TStream; var IsValidHeaderButNeedMoreData : Boolean) : Boolean;
 Var lastp : Integer;
   c : Cardinal;
@@ -2124,7 +2141,7 @@ end;
 procedure TNetServer.OnNewIncommingConnection(Sender : TObject; Client : TNetTcpIpClient);
 Var n : TNetServerClient;
   DebugStep : String;
-  tc : Cardinal;
+  tc : TTickCount;
 begin
   DebugStep := '';
   Try
@@ -2157,10 +2174,10 @@ begin
         TLog.NewLog(ltdebug,Classname,'Finalizing ServerAccept '+IntToHex(PtrInt(n),8)+' '+n.ClientRemoteAddr);
         DebugStep := 'Disconnecting NetServerClient';
         n.Connected := false;
-        tc := GetTickCount;
+        tc := TPlatform.GetTickCount;
         Repeat
           sleep(10); // 1.5.4 -> To prevent that not client disconnected (and not called OnDisconnect), increase sleep time
-        Until (Not n.Connected) Or (tc + 5000 < GetTickCount);
+        Until (Not n.Connected) Or (tc + 5000 < TPlatform.GetTickCount);
         sleep(5);
         DebugStep := 'Assigning old client';
         n.SetClient( NetTcpIpClientClass.Create(Nil) );
@@ -2382,7 +2399,7 @@ begin
     ms.Free;
   end;
   If ((FLastDataReceivedTS>0) Or ( NOT (Self is TNetServerClient)))
-     AND ((FLastDataReceivedTS+(1000*FRandomWaitSecondsSendHello)<GetTickCount) AND (FLastDataSendedTS+(1000*FRandomWaitSecondsSendHello)<GetTickCount)) then begin
+     AND ((FLastDataReceivedTS+(1000*FRandomWaitSecondsSendHello)<TPlatform.GetTickCount) AND (FLastDataSendedTS+(1000*FRandomWaitSecondsSendHello)<TPlatform.GetTickCount)) then begin
      // Build 1.4 -> Changing wait time from 120 secs to a random seconds value
     If TNetData.NetData.PendingRequest(Self,ops)>=2 then begin
       TLog.NewLog(ltDebug,Classname,'Pending requests without response... closing connection to '+ClientRemoteAddr+' > '+ops);
@@ -3238,11 +3255,10 @@ end;
 function TNetConnection.DoSendAndWaitForResponse(operation: Word;
   RequestId: Integer; SendDataBuffer, ReceiveDataBuffer: TStream;
   MaxWaitTime: Cardinal; var HeaderData: TNetHeaderData): Boolean;
-var tc : Cardinal;
+var tc : TTickCount;
   was_waiting_for_response : Boolean;
-  l : TList;
-  i : Integer;
   iDebugStep : Integer;
+  reservedResponse : TMemoryStream;
 begin
   iDebugStep := 0;
   Try
@@ -3256,7 +3272,7 @@ begin
     If Not Assigned(FTcpIpClient) then exit;
     if Not Client.Connected then exit;
     iDebugStep := 110;
-    tc := GetTickCount;
+    tc := TPlatform.GetTickCount;
     If TPCThread.TryProtectEnterCriticalSection(Self,MaxWaitTime,FNetLock) then begin
       Try
         iDebugStep := 120;
@@ -3270,10 +3286,10 @@ begin
           iDebugStep := 300;
           Repeat
             iDebugStep := 400;
-            if (MaxWaitTime > GetTickCount - tc) then MaxWaitTime := MaxWaitTime - (GetTickCount - tc)
+            if (MaxWaitTime > TPlatform.GetTickCount - tc) then MaxWaitTime := MaxWaitTime - (TPlatform.GetTickCount - tc)
             else MaxWaitTime := 1;
             If (MaxWaitTime>60000) then MaxWaitTime:=60000;
-            tc := GetTickCount;
+            tc := TPlatform.GetTickCount;
             if (ReadTcpClientBuffer(MaxWaitTime,HeaderData,ReceiveDataBuffer)) then begin
               iDebugStep := 500;
               TNetData.NetData.NodeServersAddresses.UpdateNetConnection(Self);
@@ -3323,6 +3339,23 @@ begin
                     if (HeaderData.header_type=ntp_request) then
                       DoProcess_GetAccount_Request(HeaderData,ReceiveDataBuffer)
                     else TLog.NewLog(ltdebug,Classname,'Received old response of: '+TNetData.HeaderDataToText(HeaderData));
+                  end;
+                  CT_NetOp_Reserved_Start..CT_NetOp_Reserved_End : Begin
+                    // This will allow to do nothing if not implemented
+                    reservedResponse := TMemoryStream.Create;
+                    Try
+                      TNetData.NetData.DoProcessReservedAreaMessage(Self,HeaderData,ReceiveDataBuffer,reservedResponse);
+                      if (HeaderData.header_type=ntp_request) then begin
+                        if (reservedResponse.Size>0) then begin
+                          Send(ntp_response,HeaderData.operation,0,HeaderData.request_id,reservedResponse);
+                        end else begin
+                          // If is a request, and DoProcessReservedAreaMessage didn't filled reservedResponse, will response with ERRORCODE_NOT_IMPLEMENTED
+                          Send(ntp_response,HeaderData.operation, CT_NetOp_ERRORCODE_NOT_IMPLEMENTED ,HeaderData.request_id,Nil);
+                        end;
+                      end;
+                    finally
+                      reservedResponse.Free;
+                    end;
                   end
                 else
                   DisconnectInvalidClient(false,'Invalid operation: '+TNetData.HeaderDataToText(HeaderData));
@@ -3330,7 +3363,7 @@ begin
               end;
             end else sleep(1);
             iDebugStep := 900;
-          Until (Result) Or (GetTickCount>(MaxWaitTime+tc)) Or (Not Connected) Or (FDoFinalizeConnection);
+          Until (Result) Or (TPlatform.GetTickCount>(MaxWaitTime+tc)) Or (Not Connected) Or (FDoFinalizeConnection);
         finally
           if was_waiting_for_response then FIsWaitingForResponse := false;
         end;
@@ -3379,7 +3412,7 @@ end;
 function TNetConnection.ReadTcpClientBuffer(MaxWaitMiliseconds: Cardinal; var HeaderData: TNetHeaderData; BufferData: TStream): Boolean;
 var
   auxstream : TMemoryStream;
-  tc : Cardinal;
+  tc : TTickCount;
   last_bytes_read, t_bytes_read : Int64;
   //
   IsValidHeaderButNeedMoreData : Boolean;
@@ -3393,7 +3426,7 @@ begin
   BufferData.Size := 0;
   TPCThread.ProtectEnterCriticalSection(Self,FNetLock);
   try
-    tc := GetTickCount;
+    tc := TPlatform.GetTickCount;
     repeat
       If not Connected then exit;
       if Not Client.Connected then exit;
@@ -3439,7 +3472,7 @@ begin
         try
           last_bytes_read := auxstream.size;
           if last_bytes_read>0 then begin
-            FLastDataReceivedTS := GetTickCount;
+            FLastDataReceivedTS := TPlatform.GetTickCount;
             FRandomWaitSecondsSendHello := 90 + Random(60);
 
             FClientBufferRead.Position := FClientBufferRead.size; // Go to the end
@@ -3453,19 +3486,19 @@ begin
           (Client as TBufferedNetTcpIpClient).ReadBufferUnlock;
         end;
       end;
-    until (Result) Or ((GetTickCount > (tc+MaxWaitMiliseconds)) And (last_bytes_read=0));
+    until (Result) Or ((TPlatform.GetTickCount > (tc+MaxWaitMiliseconds)) And (last_bytes_read=0));
   finally
     Try
       if (Connected) then begin
         if (Not Result) And (FClientBufferRead.Size>0) And (Not IsValidHeaderButNeedMoreData) then begin
           deletedBytes := FClientBufferRead.Size;
           TLog.NewLog(lterror,ClassName,Format('Deleting %d bytes from TcpClient buffer of %s after max %d miliseconds. Elapsed: %d',
-            [deletedBytes, Client.ClientRemoteAddr,MaxWaitMiliseconds,GetTickCount-tc]));
+            [deletedBytes, Client.ClientRemoteAddr,MaxWaitMiliseconds,TPlatform.GetTickCount-tc]));
           FClientBufferRead.Size:=0;
           DisconnectInvalidClient(false,'Invalid data received in buffer ('+inttostr(deletedBytes)+' bytes)');
         end else if (IsValidHeaderButNeedMoreData) then begin
           TLog.NewLog(ltDebug,ClassName,Format('Not enough data received - Received %d bytes from TcpClient buffer of %s after max %d miliseconds. Elapsed: %d - HeaderData: %s',
-            [FClientBufferRead.Size, Client.ClientRemoteAddr,MaxWaitMiliseconds,GetTickCount-tc,TNetData.HeaderDataToText(HeaderData)]));
+            [FClientBufferRead.Size, Client.ClientRemoteAddr,MaxWaitMiliseconds,TPlatform.GetTickCount-tc,TNetData.HeaderDataToText(HeaderData)]));
         end;
       end;
     Finally
@@ -3548,7 +3581,7 @@ begin
         ' Size:'+InttoStr(Buffer.Size)+'b '+s+'to '+
         ClientRemoteAddr);
       (Client as TBufferedNetTcpIpClient).WriteBufferToSend(Buffer);
-      FLastDataSendedTS := GetTickCount;
+      FLastDataSendedTS := TPlatform.GetTickCount;
       FRandomWaitSecondsSendHello := 90 + Random(60);
     Finally
       FNetLock.Release;
@@ -3949,14 +3982,14 @@ Var l : TList;
   netserverclientstop : TNetServerClient;
   newstats : TNetStatistics;
 begin
-  FLastCheckTS := GetTickCount;
+  FLastCheckTS := TPlatform.GetTickCount;
   while (Not Terminated) do begin
-    if ((GetTickCount>(FLastCheckTS+1000)) AND (Not FNetData.FIsDiscoveringServers)) then begin
+    if ((TPlatform.GetTickCount>(FLastCheckTS+1000)) AND (Not FNetData.FIsDiscoveringServers)) then begin
       nactive := 0;
       ndeleted := 0;
       nserverclients := 0;
       netserverclientstop := Nil;
-      FLastCheckTS := GetTickCount;
+      FLastCheckTS := TPlatform.GetTickCount;
       If (FNetData.FNetConnections.TryLockList(100,l)) then begin
         try
           newstats := CT_TNetStatistics_NUL;