Saltar al contenido

“No hay espacio de búfer disponible” al conectar

Elena, miembro de nuestro equipo, nos ha hecho el favor de escribir esta crónica ya que controla a la perfección dicho tema.

Solución:

Bueno, no sé cuál es exactamente el problema, pero intentaré encontrar la dirección correcta para resolverlo.

los ENOBUFS el código se devuelve cuando sk_alloc() o dst_alloc() es fallido No puedo encontrar ninguna otra aparición de ENOBUFS en el código fuente relacionado con los sockets.

Además, no puedo encontrar ningún camino desde el SYSCALL_DEFINE3(connect) a sk_alloc()y creo que el socket no debe asignarse durante connect() llame donde obtiene el error, por lo que creo que no es probable que el sk_alloc() causó el problema.

los dst_alloc() es probable que se utilice para comprobar las rutas durante el connect()no puedo encontrar la ruta exacta, debe estar en algún lugar dentro: SYSCALL_DEFINE3(connect) -> .connect() -> ip4_datagram_connect() -> ip_route_connect()

los dst_alloc() asigna una entrada en un caché SLAB correspondiente, y en realidad puede fallar si el caché está lleno. En realidad, las entradas antiguas deben eliminarse si eso sucede, pero tal vez haya casos en los que aún devuelva un error.

Así que creo que puedes moverte en esta dirección. El tamaño de caché dst puede cambiar a través de /proc/sys/net/ipv4/route/max_size. Primero, verifique si la configuración (o cualquier otra configuración en sys.net.ipv4.route) se cambia por “ajustes de TCP aleatorios que se muestran en Google”.

En los núcleos anteriores a 3.6, ENOBUFS podría haberlo afectado por el tráfico normal de IPv4/v6, cuando el límite de net.ipv4.route.max_size o net.ipv6.route.max_size se agotó, en consecuencia.

A partir del kernel 3.6, se eliminó el caché de enrutamiento y net.ipv4.route.max_size perdió su influencia en la cantidad de entradas de dst. Entonces, en general, eso ya no sería posible.

Sin embargo, aún puede encontrarse con este error como yo, al usar IPSec. Después de cierta cantidad de túneles IPSec creados, no pude hacer ping al host remoto:

# ping 10.100.0.1
connect: No buffer space available

ping de iputils crea un descriptor de archivo de prueba y usa connect() en él para vincular el dst ip. Cuando sucede, el kernel crea la entrada de caché dst para el AF dado, y el límite de entradas de caché xfrm4 dst ya se agotó en mi caso. Este límite está controlado por la configuración de sysctl:

xfrm4_gc_thresh - INTEGER
    The threshold at which we will start garbage collecting for IPv4
    destination cache entries.  At twice this value the system will
    refuse new allocations.

Me encontré con esto usando el kernel 3.10.59, donde el límite predeterminado es muy bajo: 1024. A partir del kernel 3.10.83, este límite se incrementó a 32768 y sería mucho más difícil de alcanzar.

Entonces, emití:

# sysctl net.ipv4.xfrm4_gc_thresh=32768

y lo hizo por mí.

Ruta aproximada en kernel para mi caso con IPSec:

ip4_datagram_connect() -> ip_route_connect() -> ip_route_output_flow() ->
xfrm_lookup() -> xfrm_resolve_and_create_bundle() ->
... -> xfrm_alloc_dst() -> dst_alloc() with xfrm4_dst_ops, where gc is set.

Si conservas algún titubeo y forma de progresar nuestro artículo eres capaz de realizar un exégesis y con placer lo leeremos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *