.net wcf net.pipe

.net - La aplicación de terceros rompe nuestra aplicación WCF



net.pipe (3)

Nuestra aplicación utiliza WCF en tuberías con nombre para comunicarse entre dos procesos (nota: ninguno de los procesos es un servicio de Windows). Nuestra aplicación ha estado funcionando en el campo sin incidentes desde hace un par de años.

Ahora estamos recibiendo informes de que la presencia de una aplicación de terceros (específicamente, Garmin Express) está rompiendo la nuestra. Instalé Garmin Express en mi casa y confirmé el comportamiento. Específicamente, el "Servicio de actualización de Garmin Core", cuando se ejecuta, hace que nuestra aplicación falle.

Cuando se ejecuta el servicio de Garmin, se inicia el lado del "servicio" de nuestra aplicación y no tiene problemas para crear el punto final WCF. Pero cuando el cliente inicia e intenta conectarse al servicio, falla con EndpointNotFoundException, como si el servicio ni siquiera se estuviera ejecutando.

En este punto, puedo detener literalmente el servicio de Garmin desde el panel de control de Servicios, luego volver a ejecutar el cliente con éxito sin siquiera reiniciar nuestro propio servicio. Si vuelvo a iniciar el servicio de Garmin, fallan los intentos posteriores de iniciar el cliente. Por lo tanto, esto al menos demuestra que nuestro servicio WCF está funcionando todo el tiempo, y el software de Garmin de alguna manera está bloqueando la capacidad de nuestro cliente para conectarse.

Estamos utilizando nuestro propio nombre para la dirección del punto final (por ejemplo, algo así como "net.pipe: // localhost / MyPrivateApplication"). Intenté cambiar esta dirección por otros nombres, pero eso no tiene ningún efecto sobre el problema.

¿Cómo puede otra aplicación, simplemente ejecutando, romper la capacidad de nuestra propia aplicación de usar WCF?

Actualización: por solicitud, aquí hay un fragmento de código del lado del servicio. Lo simplifiqué de nuestro código original en un intento de aislar el problema. Hasta el momento, ni un solo cambio que haya hecho ha tenido algún efecto sobre el tema.

MyService service = new MyService(); ServiceHost host = new ServiceHost(service); string hostAddress = new Uri("net.pipe://localhost/MyWCFConnection"); host.AddServiceEndpoint(typeof(IMyService), new NetNamedPipeBinding(), hostAddress); host.Open();


En Microsoft, hemos reducido el problema a la forma en que Garmin Core Update Service crea conductos con nombre. Los conductos con nombre se pueden crear en diferentes ámbitos: global y local. El alcance global es esencialmente de toda la máquina y Local es específico para el usuario. La aplicación de Garmin es

a. ejecutándose como servicio del sistema, por lo que el alcance para escuchar el servicio de canalización con nombre es global.

segundo. escuchando en la dirección raíz de "net.pipe: // localhost /" (p. ej., sin subrutas / segmentos).

do. Usando un modo de comparación de nombre de host StrongWildcard.

re. Los elementos de la a a la c significan que la aplicación de Garmin es esencialmente una trampa para cualquier conexión de red que no coincida con algo más específico.

mi. También significa que Garmin bloquea completamente a todos los oyentes que usan un alcance local

La solución ideal para esto sería un cambio en la aplicación Garmin de modo que registre su oyente net.pipe con una url más específica.


Una posible respuesta a su pregunta "¿Cómo puede otra aplicación, simplemente ejecutando, romper nuestra propia aplicación ...":

  1. La otra aplicación también usa WCF NetNamedPipeBinding.
  2. Ambas aplicaciones crean puntos finales de servicio utilizando base + URL relativas.
  3. La elección de la dirección base de las aplicaciones y HostNameComparisonMode es tal que existe una colisión de nombre entre las aplicaciones en una de las variantes de URL usadas por la pila WCF del lado del cliente para ubicar los metadatos del servicio .

No tengo idea si el servicio Garmin realmente usa WCF NetNamedPipeBinding, pero esta es una posibilidad que debes investigar. El problema se puede evitar utilizando siempre URL absolutas para puntos finales NetNamedPipe .

De acuerdo, entonces, después de las actualizaciones de la pregunta, ahora sabemos que el servicio Garmin está usando WCF NetNamedPipeBinding, y sabemos que su aplicación registra su servicio usando una dirección absoluta, por lo que la explicación anterior no es la historia completa.

Aquí hay otra hipótesis:

  1. Supongamos que el servicio de Garmin se ejecuta en un proceso que tiene el privilegio de seguridad SeCreateGlobalPrivilege (que tendrá un servicio de Windows a menos que esté codificado especialmente para deshabilitar el privilegio).
  2. Supongamos que también registra su punto final WCF Named Pipe con una dirección base de net.pipe: // localhost y direcciones relativas de punto final.
  3. Ahora sus metadatos de servicio se publicarán utilizando un objeto de asignación de memoria compartida con un nombre en el espacio de nombres Global.
  4. Su aplicación de servicio no es un servicio de Windows. Mi hipótesis es que su proceso no tiene el privilegio de seguridad SeCreateGlobalPrivilege. Si este es el caso, sus metadatos de servicio se publicarán usando un objeto de asignación de memoria compartida en su espacio de nombre de sesión local solamente.
  5. Ahora su proceso de cliente intenta iniciar una conexión cuando se está ejecutando el servicio de Garmin ... el elemento de la pila de canales WCF del lado del cliente elemento NetNamedPipeBinding intenta localizar los metadatos del servicio para su servicio según su URL de servicio net.pipe: // localhost / MyWCFConnection . Como se explica en el enlace anterior, ejecutará la búsqueda utilizando varias variantes de la URL del servicio para derivar un nombre para el objeto de memoria compartida que contiene los metadatos. En primer lugar, busca en el espacio de nombres Global la lista completa de variantes, antes de buscar en el espacio de nombres Local.
  6. En este caso, el primer intento será para el nombre derivado de "net.pipe: // + / MyWCFConnection", y presumiblemente no puede encontrar un objeto con este nombre en el espacio de nombres Global.
  7. Sin embargo, el segundo intento se basará en la variante "net.pipe: // + /", y coincidirá con el nombre de la asignación de memoria compartida del servicio Garmin publicada en el espacio de nombres Global. Debido a la orden de búsqueda, nunca llegará a los metadatos de su servicio publicados en el espacio de nombres de la sesión Local.
  8. Su cliente intenta conectarse a la tubería del servicio Garmin. Supongamos que el servicio de Garmin tiene implementada alguna seguridad que da como resultado el rechazo de su cliente con un acceso denegado (por ejemplo, puede establecer una ACL en su canalización ). El resultado bien podría aparecer como una EndpointNotFoundException. [ EDICION MÁS TARDE: en realidad, lo más probable es que tu cliente se esté conectando al servicio de Garmin, inicie el protocolo de enlace de preámbulo y reciba un error de protocolo de trama ( http://schemas.microsoft.com/ws/) 2006/05 / framing / faults / EndpointNotFound ) porque la URL solicitada en el registro Via no coincidirá con lo que espera el servicio Garmin. El enlace está soltando la conexión y presentando esta falla en su código de cliente como una EndpointNotFoundException.]

¿Qué puedes hacer al respecto? Yo sugeriría:

  • Si se puede confirmar la hipótesis anterior o algo similar, y Garmin está utilizando un direccionamiento relativo + base con una base de net.pipe: // localhost, lo mejor sería hacer que se apropien del problema: podrían solucionar ese problema muy fácilmente cambiando su dirección base a algo más probable que sea único.
  • Quizá pueda evitarlo encontrando la forma de que su aplicación de servicio se ejecute con el privilegio de seguridad SeCreateGlobalPrivilege: esto no es fácil sin convertirlo en un servicio de Windows o ejecutar como administrador, pero tal vez no sea imposible. Entonces sus metadatos también se publicarán en el espacio de nombres Global y la búsqueda del cliente lo encontraría antes de Garmin.
  • [Editar más tarde] Tal vez haya una solución que implique establecer la propiedad HostNameComparisonMode del enlace a Exact y usar un sinónimo para localhost como la parte del host de la URL del servicio (por ejemplo, net.pipe: //127.0.0.1/MyWCFConnection). Esto puede dirigir la búsqueda en torno a las variantes de Garmin para que su cliente tenga la oportunidad de considerar nombres en el espacio de nombres de la sesión local. No sé si funcionará, pero vale la pena intentarlo, lo habría pensado.
  • Y una posibilidad muy remota: ¿su empresa tiene una relación de soporte de producto con Microsoft? Podría decirse que este es un defecto de diseño serio en WCF: si le haces un escándalo, es posible que Microsoft emita un parche QFE para ello, por ejemplo, para proporcionar una propiedad vinculante para decirle a la pila del lado del cliente que solo pruebe el espacio de nombres Local.

He encontrado un método para mostrar qué aplicaciones usan net.pipe (aunque no necesariamente cuáles lo están usando incorrectamente).

Primero descargue la aplicación Handle desde sysinternals:

https://technet.microsoft.com/en-us/sysinternals/handle.aspx?f=255&MSPPError=-2147217396

A continuación, abra un símbolo del sistema como administrador y ejecute "Handle.exe net.pipe" (menos comillas). Esto mostrará una lista de todas las aplicaciones que usan net.pipe y que se están ejecutando actualmente. Desde allí, puedes matar o inhabilitar uno a la vez, hasta que descubras a tu culpable. Casi nunca tengo más de 4-5 procesos usándolo. Si no ejecuta el símbolo del sistema como administrador, puede dar 0 resultados.

A continuación se muestran todas las aplicaciones que he encontrado que interfieren con net.pipe:

  • "HP Support Solutions Framework Service" : solo algunas versiones afectadas
  • "Servicio de actualización de Garmin Core" : corregido en las versiones más recientes pero fuera de caja está roto
  • "Servicio WBE" : utilizado por un par de laptops Dell junto con una estación de conexión inalámbrica
  • Servicio "Intel (R) Security Assist" : lo vi en un par de computadoras portátiles Win10 a principios de 2016.
  • "Servicio WSA de Baraccuda" - Agente de seguridad web. Probablemente molestaría a un cliente si deshabilitó esto.
  • "DropboxOEM.exe" : una variante de Dropbox para incluir en las PC compradas en la tienda. Solo notado en Win10 hasta el momento. Este es único, porque es el primero que he descubierto que no es un servicio de Windows, lo mejor que puedo decir.
  • "Servicio de MTC" : instalado en algunas PC de la marca Getac. Inseguro de lo que hace
  • "pcdrcui.exe" - No es un servicio, pero se ejecuta como administrador. Componente de SupportAssist de Dell.

Admito una aplicación que requiere net.pipe, así que actualizaré esta lista a medida que encuentre más servicios que lo hagan.