{"id":44146535,"url":"https://github.com/hayabusa-cloud/sock","last_synced_at":"2026-02-17T08:10:15.893Z","repository":{"id":331472803,"uuid":"1120138860","full_name":"hayabusa-cloud/sock","owner":"hayabusa-cloud","description":"Zero-allocation socket library for Unix systems in pure Go","archived":false,"fork":false,"pushed_at":"2026-02-06T16:27:05.000Z","size":293,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-06T17:39:00.268Z","etag":null,"topics":["golang","io-uring","socket"],"latest_commit_sha":null,"homepage":"https://code.hybscloud.com/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hayabusa-cloud.png","metadata":{"files":{"readme":"README.es.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"hayabusa-cloud"}},"created_at":"2025-12-20T15:13:10.000Z","updated_at":"2026-02-06T12:50:17.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/hayabusa-cloud/sock","commit_stats":null,"previous_names":["hayabusa-cloud/sock"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/hayabusa-cloud/sock","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hayabusa-cloud%2Fsock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hayabusa-cloud%2Fsock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hayabusa-cloud%2Fsock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hayabusa-cloud%2Fsock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hayabusa-cloud","download_url":"https://codeload.github.com/hayabusa-cloud/sock/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hayabusa-cloud%2Fsock/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29254311,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-09T01:52:29.835Z","status":"online","status_checked_at":"2026-02-09T02:00:09.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["golang","io-uring","socket"],"created_at":"2026-02-09T02:17:23.614Z","updated_at":"2026-02-17T08:10:15.880Z","avatar_url":"https://github.com/hayabusa-cloud.png","language":"Go","funding_links":["https://github.com/sponsors/hayabusa-cloud"],"categories":[],"sub_categories":[],"readme":"# sock\n\n[![Go Reference](https://pkg.go.dev/badge/code.hybscloud.com/sock.svg)](https://pkg.go.dev/code.hybscloud.com/sock)\n[![Go Report Card](https://goreportcard.com/badge/github.com/hayabusa-cloud/sock)](https://goreportcard.com/report/github.com/hayabusa-cloud/sock)\n[![Codecov](https://codecov.io/gh/hayabusa-cloud/sock/graph/badge.svg)](https://codecov.io/gh/hayabusa-cloud/sock)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nTipos de socket sin asignaciones y maquinaria de direcciones para sistemas Unix en Go.\n\nIdioma: [English](./README.md) | [简体中文](./README.zh-CN.md) | **Español** | [日本語](./README.ja.md) | [Français](./README.fr.md)\n\n## Cuándo Usar Este Paquete\n\nUse `sock` en lugar del paquete estándar `net` cuando necesite:\n\n- **Rutas calientes sin asignaciones** — Los tipos Sockaddr codifican directamente al formato del kernel sin asignación de heap\n- **I/O no bloqueante** — Las operaciones retornan `iox.ErrWouldBlock` inmediatamente en lugar de bloquear goroutines\n- **Control directo del kernel** — Opciones de socket, TCP_INFO y otras características de bajo nivel\n- **Integración con io_uring** — Todos los sockets exponen `iofd.FD` para I/O asíncrona\n\nPara aplicaciones típicas donde la latencia no es crítica, el paquete estándar `net` proporciona una API más simple y portable.\n\n## Características\n\n- **Direcciones Sin Asignaciones** — Los tipos Sockaddr codifican directamente al formato del kernel sin asignación de heap\n- **Soporte de Protocolos** — TCP, UDP, SCTP, Unix (stream/dgram/seqpacket), Raw IP\n- **Listo para io_uring** — Todos los sockets exponen `iofd.FD` para integración de I/O asíncrona\n- **Syscalls Sin Overhead** — Interacción directa con el kernel via ensamblador `zcall`\n\n## Arquitectura\n\n### Interfaz Sockaddr\n\nLa interfaz `Sockaddr` es la base del manejo de direcciones sin asignaciones:\n\n```go\ntype Sockaddr interface {\n    Raw() (unsafe.Pointer, uint32)  // Formato kernel directo\n    Family() uint16                  // AF_INET, AF_INET6, AF_UNIX\n}\n```\n\nLos tipos de dirección (`SockaddrInet4`, `SockaddrInet6`, `SockaddrUnix`) embeben estructuras kernel crudas y devuelven punteros directamente—sin marshaling, sin asignación.\n\n### Jerarquía de Tipos de Socket\n\n```\nNetSocket (base)\n├── TCPSocket → TCPConn, TCPListener\n├── UDPSocket → UDPConn\n├── SCTPSocket → SCTPConn, SCTPListener (Linux)\n├── UnixSocket → UnixConn, UnixListener\n└── RawSocket → RawConn (CAP_NET_RAW)\n```\n\nTodos los sockets exponen `FD() *iofd.FD` para integración con io_uring y otros mecanismos de I/O asíncrona.\n\n### Integración con el Kernel\n\n```\nAplicación\n    ↓\nsock.TCPConn.Write(data)\n    ↓\niofd.FD.Write()\n    ↓\nzcall.Write() ← Punto de entrada en ensamblador (sin runtime Go)\n    ↓\nKernel Linux\n```\n\nEl paquete `zcall` proporciona puntos de entrada de syscall crudos que evitan los hooks del runtime de Go, eliminando el overhead del scheduler para rutas críticas de latencia.\n\n### Semánticas de I/O Adaptativa\n\nEl paquete implementa el modelo **Strike-Spin-Adapt** para I/O no bloqueante:\n\n1. **Strike**: Ejecución directa de syscall (no bloqueante)\n2. **Spin**: Sincronización a nivel de hardware (manejada por `sox` si es necesario)\n3. **Adapt**: Backoff de software ajustado para red cuando se establecen deadlines\n\n**Comportamientos clave:**\n\n- **No bloqueante por defecto**: Las operaciones `Read`, `Write`, `Accept` y `Dial` retornan inmediatamente con `iox.ErrWouldBlock` si el kernel no está listo.\n- **Adaptación dirigida por deadline**: Solo cuando se establece explícitamente un deadline (via `SetDeadline`, `SetReadDeadline` o `SetWriteDeadline`) la operación entra en un bucle de reintentos con backoff progresivo.\n- **Dial no bloqueante**: A diferencia de `net.Dial`, funciones como `DialTCP4` retornan inmediatamente una vez que comienza el intento de conexión. El handshake TCP puede estar aún en progreso (`ErrInProgress` se ignora silenciosamente). Use `TCPDialer` con timeout para comportamiento bloqueante:\n\n```go\n// No bloqueante (retorna inmediatamente, handshake puede estar en progreso)\nconn, _ := sock.DialTCP4(nil, raddr)\n\n// Bloqueante con timeout (espera conexión o timeout)\ndialer := \u0026sock.TCPDialer{Timeout: 5 * time.Second}\nconn, _ := dialer.Dial4(nil, raddr)\n```\n\n## Instalación\n\n```bash\ngo get code.hybscloud.com/sock\n```\n\n## Uso\n\n### TCP\n\n```go\n// Servidor\nln, _ := sock.ListenTCP4(\u0026sock.TCPAddr{IP: net.ParseIP(\"0.0.0.0\"), Port: 8080})\nconn, _ := ln.Accept()\nconn.Read(buf)\nconn.Close()\n\n// Cliente\nconn, _ := sock.DialTCP4(nil, \u0026sock.TCPAddr{IP: net.ParseIP(\"127.0.0.1\"), Port: 8080})\nconn.SetNoDelay(true)\nconn.Write(data)\n```\n\n### UDP\n\n```go\n// Servidor\nconn, _ := sock.ListenUDP4(\u0026sock.UDPAddr{Port: 5353})\nn, addr, _ := conn.ReadFrom(buf)\nconn.WriteTo(response, addr)\n\n// Cliente\nconn, _ := sock.DialUDP4(nil, \u0026sock.UDPAddr{IP: net.ParseIP(\"8.8.8.8\"), Port: 53})\nconn.Write(query)\nconn.Read(response)\n```\n\n### SCTP (Solo Linux)\n\n```go\n// Servidor\nln, _ := sock.ListenSCTP4(\u0026sock.SCTPAddr{IP: net.ParseIP(\"0.0.0.0\"), Port: 9000})\nconn, _ := ln.Accept()\nconn.Read(buf)\n\n// Cliente con timeout\ndialer := \u0026sock.SCTPDialer{Timeout: 5 * time.Second}\nconn, _ := dialer.Dial4(nil, \u0026sock.SCTPAddr{IP: net.ParseIP(\"127.0.0.1\"), Port: 9000})\nconn.Write(data)\n```\n\n### Sockets de Dominio Unix\n\n```go\n// Stream\nln, _ := sock.ListenUnix(\"unix\", \u0026net.UnixAddr{Name: \"/tmp/app.sock\"})\nconn, _ := ln.Accept()\n\n// Datagrama\nconn, _ := sock.ListenUnixgram(\"unixgram\", \u0026net.UnixAddr{Name: \"/tmp/app.dgram\"})\n\n// Par de sockets\npair, _ := sock.UnixConnPair(\"unix\")\npair[0].Write([]byte(\"ping\"))\npair[1].Read(buf)\n```\n\n### Sockets Raw (requiere CAP_NET_RAW)\n\n```go\n// ICMP ping\nsock, _ := sock.NewICMPSocket4()\nsock.SendTo(icmpPacket, \u0026net.IPAddr{IP: net.ParseIP(\"8.8.8.8\")})\nn, addr, _ := sock.RecvFrom(buf)\n```\n\n### Opciones de Socket\n\n```go\n// Ajuste TCP\nconn.SetNoDelay(true)              // Deshabilitar algoritmo de Nagle\nconn.SetKeepAlive(true)            // Habilitar sondas keepalive\nconn.SetKeepAlivePeriod(30 * time.Second)\n\n// Tamaños de buffer\nsock.SetSendBuffer(conn.FD(), 256*1024)\nsock.SetRecvBuffer(conn.FD(), 256*1024)\n\n// SO_LINGER para RST inmediato al cerrar\nsock.SetLinger(conn.FD(), true, 0)\n\n// TCP_USER_TIMEOUT para detección de conexiones muertas (Linux)\nsock.SetTCPUserTimeout(conn.FD(), 30000)  // 30 segundos en milisegundos\n\n// TCP_NOTSENT_LOWAT para reducir memoria y latencia (Linux)\nsock.SetTCPNotsentLowat(conn.FD(), 16384)\n\n// SO_BUSY_POLL para polling de baja latencia (Linux)\nsock.SetBusyPoll(conn.FD(), 50)  // 50 microsegundos\n```\n\n### Operaciones UDP por Lotes (Linux)\n\n```go\n// Enviar múltiples mensajes en una sola llamada al sistema\nmsgs := []sock.UDPMessage{\n    {Addr: addr1, Buffers: [][]byte{data1}},\n    {Addr: addr2, Buffers: [][]byte{data2}},\n}\nn, _ := conn.SendMessages(msgs)\n\n// Recibir múltiples mensajes\nrecvMsgs := []sock.UDPMessage{\n    {Buffers: [][]byte{make([]byte, 1500)}},\n    {Buffers: [][]byte{make([]byte, 1500)}},\n}\nn, _ = conn.RecvMessages(recvMsgs)\n\n// UDP GSO (Descarga de Segmentación Genérica)\nsock.SetUDPSegment(conn.FD(), 1400)  // Tamaño de segmento\n\n// UDP GRO (Descarga de Recepción Genérica)\nsock.SetUDPGRO(conn.FD(), true)\n```\n\n### Manejo de Errores\n\n```go\n// Lectura no bloqueante con iox.ErrWouldBlock\nn, err := conn.Read(buf)\nif err == iox.ErrWouldBlock {\n    // Kernel no listo, integrar con event loop o reintentar después\n    return\n}\nif err != nil {\n    // Error real (conexión reseteada, cerrada, etc.)\n    return\n}\n\n// Lectura bloqueante con deadline\nconn.SetReadDeadline(time.Now().Add(5 * time.Second))\nn, err = conn.Read(buf)\nif err == sock.ErrTimedOut {\n    // Deadline excedido\n}\n```\n\n### Compatibilidad con el Paquete net\n\nEl paquete proporciona conversión transparente con los tipos estándar de Go `net`:\n\n```go\n// Convertir net.TCPAddr a Sockaddr (sin asignación)\nnetAddr := \u0026net.TCPAddr{IP: net.ParseIP(\"127.0.0.1\"), Port: 8080}\nsockaddr := sock.TCPAddrToSockaddr(netAddr)\n\n// Convertir de vuelta a net.TCPAddr\ntcpAddr := sock.SockaddrToTCPAddr(sockaddr)\n\n// Alias de tipos para compatibilidad\nvar _ sock.Conn = conn      // Compatible con net.Conn\nvar _ sock.Addr = addr      // Compatible con net.Addr\n\n// Nota: Los listeners devuelven tipos concretos (*TCPConn, *UnixConn) para\n// rendimiento sin asignaciones, no net.Conn como requiere net.Listener.\n```\n\n## Plataformas Soportadas\n\n| Plataforma | Estado |\n|------------|--------|\n| linux/amd64 | Completo |\n| linux/arm64 | Completo |\n| linux/riscv64 | Completo |\n| linux/loong64 | Completo |\n| darwin/arm64 | Parcial (sin SCTP, TCPInfo, multicast, SCM_RIGHTS) |\n| freebsd/amd64 | Solo cross-compile |\n\n## Licencia\n\nMIT — ver [LICENSE](./LICENSE).\n\n©2025 Hayabusa Cloud Co., Ltd.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhayabusa-cloud%2Fsock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhayabusa-cloud%2Fsock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhayabusa-cloud%2Fsock/lists"}