Jacek Caban : rpcrt4: Try reconnecting when to server in IRpcSend on broken connection.

Alexandre Julliard julliard at winehq.org
Tue Oct 16 15:53:07 CDT 2018


Module: wine
Branch: master
Commit: 3099fda2547096c3d4b258ec1cc010dabffe0b8f
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=3099fda2547096c3d4b258ec1cc010dabffe0b8f

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Oct 16 14:38:49 2018 +0200

rpcrt4: Try reconnecting when to server in IRpcSend on broken connection.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/rpcrt4/rpc_assoc.c   | 12 +++++++++---
 dlls/rpcrt4/rpc_assoc.h   |  2 +-
 dlls/rpcrt4/rpc_binding.c |  4 ++--
 dlls/rpcrt4/rpc_binding.h |  3 ++-
 dlls/rpcrt4/rpc_message.c | 42 ++++++++++++++++++++++++++++--------------
 5 files changed, 42 insertions(+), 21 deletions(-)

diff --git a/dlls/rpcrt4/rpc_assoc.c b/dlls/rpcrt4/rpc_assoc.c
index 8a823f4..044ef09 100644
--- a/dlls/rpcrt4/rpc_assoc.c
+++ b/dlls/rpcrt4/rpc_assoc.c
@@ -391,14 +391,18 @@ static RpcConnection *RpcAssoc_GetIdleConnection(RpcAssoc *assoc,
 RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc,
                                         const RPC_SYNTAX_IDENTIFIER *InterfaceId,
                                         const RPC_SYNTAX_IDENTIFIER *TransferSyntax, RpcAuthInfo *AuthInfo,
-                                        RpcQualityOfService *QOS, LPCWSTR CookieAuth, RpcConnection **Connection)
+                                        RpcQualityOfService *QOS, LPCWSTR CookieAuth,
+                                        RpcConnection **Connection, BOOL *from_cache)
 {
     RpcConnection *NewConnection;
     RPC_STATUS status;
 
     *Connection = RpcAssoc_GetIdleConnection(assoc, InterfaceId, TransferSyntax, AuthInfo, QOS);
-    if (*Connection)
+    if (*Connection) {
+        TRACE("return idle connection %p for association %p\n", *Connection, assoc);
+        if (from_cache) *from_cache = TRUE;
         return RPC_S_OK;
+    }
 
     /* create a new connection */
     status = RPCRT4_CreateConnection(&NewConnection, FALSE /* is this a server connection? */,
@@ -424,8 +428,10 @@ RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc,
     }
 
     InterlockedIncrement(&assoc->connection_cnt);
-    *Connection = NewConnection;
 
+    TRACE("return new connection %p for association %p\n", *Connection, assoc);
+    *Connection = NewConnection;
+    if (from_cache) *from_cache = FALSE;
     return RPC_S_OK;
 }
 
diff --git a/dlls/rpcrt4/rpc_assoc.h b/dlls/rpcrt4/rpc_assoc.h
index f4c5f3a..c8c8772 100644
--- a/dlls/rpcrt4/rpc_assoc.h
+++ b/dlls/rpcrt4/rpc_assoc.h
@@ -50,7 +50,7 @@ typedef struct _RpcAssoc
 RPC_STATUS RPCRT4_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, RpcAssoc **assoc) DECLSPEC_HIDDEN;
 RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc, const RPC_SYNTAX_IDENTIFIER *InterfaceId,
     const RPC_SYNTAX_IDENTIFIER *TransferSyntax, RpcAuthInfo *AuthInfo, RpcQualityOfService *QOS,
-    LPCWSTR CookieAuth, RpcConnection **Connection) DECLSPEC_HIDDEN;
+    LPCWSTR CookieAuth, RpcConnection **Connection, BOOL *from_cache) DECLSPEC_HIDDEN;
 void RpcAssoc_ReleaseIdleConnection(RpcAssoc *assoc, RpcConnection *Connection) DECLSPEC_HIDDEN;
 ULONG RpcAssoc_Release(RpcAssoc *assoc) DECLSPEC_HIDDEN;
 RPC_STATUS RpcServerAssoc_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, ULONG assoc_gid, RpcAssoc **assoc_out) DECLSPEC_HIDDEN;
diff --git a/dlls/rpcrt4/rpc_binding.c b/dlls/rpcrt4/rpc_binding.c
index ec38b86..ae63abd 100644
--- a/dlls/rpcrt4/rpc_binding.c
+++ b/dlls/rpcrt4/rpc_binding.c
@@ -272,13 +272,13 @@ RPC_STATUS RPCRT4_ReleaseBinding(RpcBinding* Binding)
 
 RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding, RpcConnection** Connection,
                               const RPC_SYNTAX_IDENTIFIER *TransferSyntax,
-                              const RPC_SYNTAX_IDENTIFIER *InterfaceId)
+                              const RPC_SYNTAX_IDENTIFIER *InterfaceId, BOOL *from_cache)
 {
   TRACE("(Binding == ^%p)\n", Binding);
 
   if (!Binding->server) {
      return RpcAssoc_GetClientConnection(Binding->Assoc, InterfaceId,
-         TransferSyntax, Binding->AuthInfo, Binding->QOS, Binding->CookieAuth, Connection);
+         TransferSyntax, Binding->AuthInfo, Binding->QOS, Binding->CookieAuth, Connection, from_cache);
   } else {
     /* we already have a connection with acceptable binding, so use it */
     if (Binding->FromConn) {
diff --git a/dlls/rpcrt4/rpc_binding.h b/dlls/rpcrt4/rpc_binding.h
index ca53887..8faacbd 100644
--- a/dlls/rpcrt4/rpc_binding.h
+++ b/dlls/rpcrt4/rpc_binding.h
@@ -174,7 +174,8 @@ RPC_STATUS RPCRT4_MakeBinding(RpcBinding** Binding, RpcConnection* Connection) D
 void       RPCRT4_AddRefBinding(RpcBinding* Binding) DECLSPEC_HIDDEN;
 RPC_STATUS RPCRT4_ReleaseBinding(RpcBinding* Binding) DECLSPEC_HIDDEN;
 RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding, RpcConnection** Connection,
-                              const RPC_SYNTAX_IDENTIFIER *TransferSyntax, const RPC_SYNTAX_IDENTIFIER *InterfaceId) DECLSPEC_HIDDEN;
+                              const RPC_SYNTAX_IDENTIFIER *TransferSyntax, const RPC_SYNTAX_IDENTIFIER *InterfaceId,
+                              BOOL *from_cache) DECLSPEC_HIDDEN;
 RPC_STATUS RPCRT4_CloseBinding(RpcBinding* Binding, RpcConnection* Connection) DECLSPEC_HIDDEN;
 
 void rpcrt4_conn_release_and_wait(RpcConnection *connection) DECLSPEC_HIDDEN;
diff --git a/dlls/rpcrt4/rpc_message.c b/dlls/rpcrt4/rpc_message.c
index 9642213..3eea88a 100644
--- a/dlls/rpcrt4/rpc_message.c
+++ b/dlls/rpcrt4/rpc_message.c
@@ -38,6 +38,7 @@
 #include "rpc_binding.h"
 #include "rpc_defs.h"
 #include "rpc_message.h"
+#include "rpc_assoc.h"
 #include "ncastatus.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(rpc);
@@ -1598,7 +1599,7 @@ RPC_STATUS WINAPI I_RpcNegotiateTransferSyntax(PRPC_MESSAGE pMsg)
     }
 
     status = RPCRT4_OpenBinding(bind, &conn, &cif->TransferSyntax,
-                                &cif->InterfaceId);
+                                &cif->InterfaceId, NULL);
 
     if (status == RPC_S_OK)
     {
@@ -1789,26 +1790,39 @@ static DWORD WINAPI async_notifier_proc(LPVOID p)
 RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg)
 {
   RpcBinding* bind = pMsg->Handle;
+  RPC_CLIENT_INTERFACE *cif;
   RpcConnection* conn;
   RPC_STATUS status;
   RpcPktHdr *hdr;
+  BOOL from_cache = TRUE;
 
   TRACE("(%p)\n", pMsg);
   if (!bind || bind->server || !pMsg->ReservedForRuntime) return RPC_S_INVALID_BINDING;
 
-  conn = pMsg->ReservedForRuntime;
-
-  hdr = RPCRT4_BuildRequestHeader(pMsg->DataRepresentation,
-                                  pMsg->BufferLength,
-                                  pMsg->ProcNum & ~RPC_FLAGS_VALID_BIT,
-                                  &bind->ObjectUuid);
-  if (!hdr)
-    return ERROR_OUTOFMEMORY;
-  hdr->common.call_id = conn->NextCallId++;
-
-  status = RPCRT4_Send(conn, hdr, pMsg->Buffer, pMsg->BufferLength);
-
-  RPCRT4_FreeHeader(hdr);
+  for (;;)
+  {
+      conn = pMsg->ReservedForRuntime;
+      hdr = RPCRT4_BuildRequestHeader(pMsg->DataRepresentation,
+                                      pMsg->BufferLength,
+                                      pMsg->ProcNum & ~RPC_FLAGS_VALID_BIT,
+                                      &bind->ObjectUuid);
+      if (!hdr)
+          return ERROR_OUTOFMEMORY;
+
+      hdr->common.call_id = conn->NextCallId++;
+      status = RPCRT4_Send(conn, hdr, pMsg->Buffer, pMsg->BufferLength);
+      RPCRT4_FreeHeader(hdr);
+      if (status == RPC_S_OK || conn->server || !from_cache)
+          break;
+
+      WARN("Send failed, trying to reconnect\n");
+      cif = pMsg->RpcInterfaceInformation;
+      RPCRT4_ReleaseConnection(conn);
+      pMsg->ReservedForRuntime = NULL;
+      status = RPCRT4_OpenBinding(bind, &conn, &cif->TransferSyntax, &cif->InterfaceId, &from_cache);
+      if (status != RPC_S_OK) break;
+      pMsg->ReservedForRuntime = conn;
+  }
 
   if (status == RPC_S_OK && pMsg->RpcFlags & RPC_BUFFER_ASYNC)
   {




More information about the wine-cvs mailing list