Commit 3099fda2 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

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

parent 3b4f3ff3
...@@ -391,14 +391,18 @@ static RpcConnection *RpcAssoc_GetIdleConnection(RpcAssoc *assoc, ...@@ -391,14 +391,18 @@ static RpcConnection *RpcAssoc_GetIdleConnection(RpcAssoc *assoc,
RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc, RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc,
const RPC_SYNTAX_IDENTIFIER *InterfaceId, const RPC_SYNTAX_IDENTIFIER *InterfaceId,
const RPC_SYNTAX_IDENTIFIER *TransferSyntax, RpcAuthInfo *AuthInfo, const RPC_SYNTAX_IDENTIFIER *TransferSyntax, RpcAuthInfo *AuthInfo,
RpcQualityOfService *QOS, LPCWSTR CookieAuth, RpcConnection **Connection) RpcQualityOfService *QOS, LPCWSTR CookieAuth,
RpcConnection **Connection, BOOL *from_cache)
{ {
RpcConnection *NewConnection; RpcConnection *NewConnection;
RPC_STATUS status; RPC_STATUS status;
*Connection = RpcAssoc_GetIdleConnection(assoc, InterfaceId, TransferSyntax, AuthInfo, QOS); *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; return RPC_S_OK;
}
/* create a new connection */ /* create a new connection */
status = RPCRT4_CreateConnection(&NewConnection, FALSE /* is this a server connection? */, status = RPCRT4_CreateConnection(&NewConnection, FALSE /* is this a server connection? */,
...@@ -424,8 +428,10 @@ RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc, ...@@ -424,8 +428,10 @@ RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc,
} }
InterlockedIncrement(&assoc->connection_cnt); 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; return RPC_S_OK;
} }
......
...@@ -50,7 +50,7 @@ typedef struct _RpcAssoc ...@@ -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 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, RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc, const RPC_SYNTAX_IDENTIFIER *InterfaceId,
const RPC_SYNTAX_IDENTIFIER *TransferSyntax, RpcAuthInfo *AuthInfo, RpcQualityOfService *QOS, 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; void RpcAssoc_ReleaseIdleConnection(RpcAssoc *assoc, RpcConnection *Connection) DECLSPEC_HIDDEN;
ULONG RpcAssoc_Release(RpcAssoc *assoc) 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; RPC_STATUS RpcServerAssoc_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, ULONG assoc_gid, RpcAssoc **assoc_out) DECLSPEC_HIDDEN;
......
...@@ -272,13 +272,13 @@ RPC_STATUS RPCRT4_ReleaseBinding(RpcBinding* Binding) ...@@ -272,13 +272,13 @@ RPC_STATUS RPCRT4_ReleaseBinding(RpcBinding* Binding)
RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding, RpcConnection** Connection, RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding, RpcConnection** Connection,
const RPC_SYNTAX_IDENTIFIER *TransferSyntax, const RPC_SYNTAX_IDENTIFIER *TransferSyntax,
const RPC_SYNTAX_IDENTIFIER *InterfaceId) const RPC_SYNTAX_IDENTIFIER *InterfaceId, BOOL *from_cache)
{ {
TRACE("(Binding == ^%p)\n", Binding); TRACE("(Binding == ^%p)\n", Binding);
if (!Binding->server) { if (!Binding->server) {
return RpcAssoc_GetClientConnection(Binding->Assoc, InterfaceId, 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 { } else {
/* we already have a connection with acceptable binding, so use it */ /* we already have a connection with acceptable binding, so use it */
if (Binding->FromConn) { if (Binding->FromConn) {
......
...@@ -174,7 +174,8 @@ RPC_STATUS RPCRT4_MakeBinding(RpcBinding** Binding, RpcConnection* Connection) D ...@@ -174,7 +174,8 @@ RPC_STATUS RPCRT4_MakeBinding(RpcBinding** Binding, RpcConnection* Connection) D
void RPCRT4_AddRefBinding(RpcBinding* Binding) DECLSPEC_HIDDEN; void RPCRT4_AddRefBinding(RpcBinding* Binding) DECLSPEC_HIDDEN;
RPC_STATUS RPCRT4_ReleaseBinding(RpcBinding* Binding) DECLSPEC_HIDDEN; RPC_STATUS RPCRT4_ReleaseBinding(RpcBinding* Binding) DECLSPEC_HIDDEN;
RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding, RpcConnection** Connection, 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; RPC_STATUS RPCRT4_CloseBinding(RpcBinding* Binding, RpcConnection* Connection) DECLSPEC_HIDDEN;
void rpcrt4_conn_release_and_wait(RpcConnection *connection) DECLSPEC_HIDDEN; void rpcrt4_conn_release_and_wait(RpcConnection *connection) DECLSPEC_HIDDEN;
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "rpc_binding.h" #include "rpc_binding.h"
#include "rpc_defs.h" #include "rpc_defs.h"
#include "rpc_message.h" #include "rpc_message.h"
#include "rpc_assoc.h"
#include "ncastatus.h" #include "ncastatus.h"
WINE_DEFAULT_DEBUG_CHANNEL(rpc); WINE_DEFAULT_DEBUG_CHANNEL(rpc);
...@@ -1598,7 +1599,7 @@ RPC_STATUS WINAPI I_RpcNegotiateTransferSyntax(PRPC_MESSAGE pMsg) ...@@ -1598,7 +1599,7 @@ RPC_STATUS WINAPI I_RpcNegotiateTransferSyntax(PRPC_MESSAGE pMsg)
} }
status = RPCRT4_OpenBinding(bind, &conn, &cif->TransferSyntax, status = RPCRT4_OpenBinding(bind, &conn, &cif->TransferSyntax,
&cif->InterfaceId); &cif->InterfaceId, NULL);
if (status == RPC_S_OK) if (status == RPC_S_OK)
{ {
...@@ -1789,26 +1790,39 @@ static DWORD WINAPI async_notifier_proc(LPVOID p) ...@@ -1789,26 +1790,39 @@ static DWORD WINAPI async_notifier_proc(LPVOID p)
RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg) RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg)
{ {
RpcBinding* bind = pMsg->Handle; RpcBinding* bind = pMsg->Handle;
RPC_CLIENT_INTERFACE *cif;
RpcConnection* conn; RpcConnection* conn;
RPC_STATUS status; RPC_STATUS status;
RpcPktHdr *hdr; RpcPktHdr *hdr;
BOOL from_cache = TRUE;
TRACE("(%p)\n", pMsg); TRACE("(%p)\n", pMsg);
if (!bind || bind->server || !pMsg->ReservedForRuntime) return RPC_S_INVALID_BINDING; if (!bind || bind->server || !pMsg->ReservedForRuntime) return RPC_S_INVALID_BINDING;
conn = pMsg->ReservedForRuntime; for (;;)
{
hdr = RPCRT4_BuildRequestHeader(pMsg->DataRepresentation, conn = pMsg->ReservedForRuntime;
pMsg->BufferLength, hdr = RPCRT4_BuildRequestHeader(pMsg->DataRepresentation,
pMsg->ProcNum & ~RPC_FLAGS_VALID_BIT, pMsg->BufferLength,
&bind->ObjectUuid); pMsg->ProcNum & ~RPC_FLAGS_VALID_BIT,
if (!hdr) &bind->ObjectUuid);
return ERROR_OUTOFMEMORY; if (!hdr)
hdr->common.call_id = conn->NextCallId++; return ERROR_OUTOFMEMORY;
status = RPCRT4_Send(conn, hdr, pMsg->Buffer, pMsg->BufferLength); hdr->common.call_id = conn->NextCallId++;
status = RPCRT4_Send(conn, hdr, pMsg->Buffer, pMsg->BufferLength);
RPCRT4_FreeHeader(hdr); 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) if (status == RPC_S_OK && pMsg->RpcFlags & RPC_BUFFER_ASYNC)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment