Réseautage Yggdrasil en Go
Aperçu
Utilisez cette compétence pour créer des programmes Go qui se connectent et servent sur le
Yggdrasil — un maillage IPv6 chiffré de bout en bout : clients, serveurs HTTP/TCP/UDP,
proxies SOCKS5, redirections de ports, et nœuds publiant des métadonnées de découverte. Le
nœud s'exécute en espace utilisateur sur une pile réseau gVisor — pas de périphérique TUN, pas de root, pas de
démon yggdrasil externe, et pas de binaire yggstack. Vous établissez des connexions et écoutez sur
Yggdrasil avec les interfaces Go standard (net.Conn, net.Listener,
net.PacketConn, http.Transport).
La bibliothèque d'intégration est github.com/voluminor/ratatoskr : créez le nœud avec
ratatoskr.New et pilotez tout via son API Go. La portée et la stabilité de
ses paquets sont résumées ci-dessous.
Conception pour un maillage contraint
Yggdrasil est un maillage superposé chiffré de bout en bout, pas un tissu de centre de données. Les liaisons sont à latence élevée, faible bande passante, sujettes aux pertes et intermittentes ; un pair joignable maintenant peut disparaître une seconde plus tard, et le trafic peut traverser de nombreux sauts. Construisez chaque solution Yggdrasil comme si elle était destinée à une connexion faible et instable. Ce n'est pas une amélioration facultative — c'est la forme par défaut d'un code correct ici.
- Jamais sans limite. Un délai d'expiration sur chaque appel et requête
(
context.WithTimeout) ; tentatives limitées ; files d'attente bornées. Pas d'attentes infinies. - Limitez la concurrence. Limitez le travail en cours :
MaxConnectionsSOCKS,SetMaxUDPSessionspour la redirection,http.Transport.MaxConnsPerHost/MaxIdleConnsPerHost, vos propres pools de workers. Par défaut, tout est illimité — définissez des limites réelles. - Segmentez les gros transferts, vérifiez, reprenez. Ne déplacez jamais un gros fichier en une seule fois.
Divisez en petits morceaux (par ex.
RangeHTTP), vérifiez chacun (taille/somme de contrôle), et rendez-le reprenable afin qu'une connexion perdue coûte un seul morceau, pas tout le transfert. - Répétez avec backoff + jitter, de manière idempotente. Attendez-vous à des déconnexions en cours d'opération. Rendez les opérations reprenables/idempotentes ; backoff exponentiel avec jitter ; limitez les tentatives.
- Gardez les charges utiles petites. Évitez les protocoles bavards et le polling ; compressez ; utilisez des encodages compacts. Gardez les NodeInfo/sigils bien en dessous de la limite de 16 Ko.
- Taille des buffers adaptée à la liaison. Utilisez
node.MTU()pour les tampons de paquets (la MTU en espace utilisateur est dynamique, plancher à 1280). - Dégradation, pas de martelage. En cas d'échec, réduisez la cadence et retournez des résultats partiels ; ne répétez jamais agressivement une tentative vers un pair ou n'inondez pas le maillage.
Un « servir un gros fichier via net/http » naïf ou « une seule requête/réponse géante » est la
mauvaise forme. La bonne forme est limitée, segmentée, reprenable, tolérante aux pannes par
défaut. Voir le modèle de transfert pour maillage contraint dans
références/intégrations.md.
Source de vérité
Le module actif est faisant autorité — pas la mémoire, pas un texte README obsolète, pas cette compétence. Avant d'écrire des conseils spécifiques à une version, inspectez ce dont le projet utilise réellement comme dépendances :
go list -m github.com/voluminor/ratatoskr # version sélectionnée
go doc github.com/voluminor/ratatoskr # API racine telle que compilée
go doc github.com/voluminor/ratatoskr/mod/peermgr ConfigObj
Pour lire le code source réel de la version sélectionnée, résolvez-le depuis le cache de modules autrement que par la devinette d'un chemin :
go list -m -f '{{.Dir}}' github.com/voluminor/ratatoskr
Ne figez pas la version minimale de Go à partir du texte README — elle peut être en retard par rapport
à la directive go.mod. Lisez le go.mod actif de la version de Ratatoskr sélectionnée.
Flux de travail par défaut
- Identifiez la forme de l'application : nœud embarqué, client/serveur HTTP, TCP/UDP brut, SOCKS5, redirection de ports, gestion de pairs, ou NodeInfo/sigils.
- Utilisez le paquet racine
github.com/voluminor/ratatoskrpour les applications. Accédez àmod/coreuniquement via le contratcore.Interface; évitez*core.Obj/UnsafeCore()sauf si un paquet de bas niveau l'exige véritablement. - Possédez un
context.Context, passez-le commeratatoskr.ConfigObj.Ctx, et utilisez quand mêmedefer node.Close()après un démarrage réussi. Les deux sont nécessaires. - Configurez les pairs à un seul endroit :
- Pairs Yggdrasil statiques :
cfg.Config.Peers - Gestionnaire de pairs Ratatoskr :
ratatoskr.ConfigObj.Peers(puis laissezcfg.Config.Peersvide, sinonNewretourneErrPeersConflict).
- Pairs Yggdrasil statiques :
- Utilisez
node.DialContextpour le TCP/UDP sortant etnode.Listen/node.ListenPacketpour les services à l'intérieur d'Yggdrasil. - Mettez les adresses IPv6 entre crochets dans les URL et les chaînes hôte-port :
http://[200:abcd::1]:8080, jamaishttp://200:abcd::1:8080. - Traitez la liaison comme faible : mettez un délai d'expiration sur chaque appel, limitez la concurrence, et segmentez/vérifiez/reprenez les gros transferts (voir Conception pour un maillage contraint).
- Lorsque vous générez du code dans un projet réel, ajoutez une vérification de compilation ou un test ciblé plutôt que de supposer que cela se compile.
Portée et stabilité du module
Les adresses Yggdrasil sont dérivées de la clé du nœud, donc la surface réseau est petite et stable. Préférez les parties que la bibliothèque considère comme finalisées ; signalez le reste explicitement plutôt que de vous appuyer dessus.
| Paquet | Statut | Utilisation via |
|---|---|---|
racine ratatoskr | Stable, API principale | New, EnableSOCKS, Ask/AskAddr, Snapshot, Close |
mod/core | Contrat stable | les méthodes core.Interface intégrées au nœud |
mod/peermgr | Stable | ratatoskr.ConfigObj.Peers |
mod/socks | Stable | node.EnableSOCKS (ne pas instancier directement) |
mod/resolver | Stable | créé automatiquement par EnableSOCKS ; l'utilisation directe est avancée |
mod/forward | Stable | forward.New → Add* → Start |
mod/sigils (+ info, services, public, inet) | Stable | ratatoskr.ConfigObj.Sigils |
mod/ninfo | Stable | node.Ask / node.AskAddr |
mod/probe | Avancé / instable — nécessite UnsafeCore(), l'API peut changer | uniquement lorsque le traçage de topologie/route est explicitement requis |
mod/settings | En cours — schéma non finalisé | à éviter ; utilisez yggdrasil-go/src/config directement |
cmd/* | Applications d'exemple, pas une API de bibliothèque importable | lisez comme modèles, n'importez jamais |
Racine vs sous-modules : par défaut, utilisez ratatoskr.New (core + SOCKS + gestionnaire de pairs
- ninfo + sigils derrière un seul
Close). Descendez àmod/coreviacore.Newuniquement pour la surface minimale (dial/listen brut), ou composez des sous-modules autour decore.Interfacepour des transports personnalisés et des tests. Chaque sous-module (peermgr/socks/forward/resolver/ninfo) prend uncore.Interface. Voir références/aperçu.md.
Sigils système — publiez ici d'abord
NodeInfo est la façon dont un nœud se décrit sur le réseau. Quatre sigils système (intégrés)
sont analysés automatiquement par chaque nœud, donc les données que vous y mettez sont
reconnues par les autres participants. Utilisez-les avant d'inventer un
sigil personnalisé ; passez-les via ratatoskr.ConfigObj.Sigils. Gardez chacun très petit — ils
partagent un budget NodeInfo de 16 Ko.
| Sigil | Ce qui va ici | Pourquoi l'utiliser |
|---|---|---|
info | Identité du nœud : nom, type, emplacement, contacts, description | Permet aux autres de savoir qui/qu'est votre nœud. |
services | Ports que vous exposez dans Yggdrasil, sous forme nom → port | Découverte de services sans scan de ports. |
public | Vos URI de peering public regroupés par réseau | Permet aux autres de se peer directement avec vous. |
inet | Vos adresses du monde réel (domaines/IP) | Mappe votre nœud Yggdrasil à une identité clearnet. |
Mettez des données standard et découvrables dans ces sigils pour que tout le réseau puisse les lire.
Ne définissez un sigil personnalisé que pour des données qu'aucun des quatre ne couvre — et rappelez-vous que seuls
les pairs exécutant votre code l'analyseront. Les constructeurs valident et retournent des erreurs ;
gérez-les avant ratatoskr.New. Détails, limites exactes, accès typé, et
création de sigils personnalisés : références/nodeinfo-sigils.md
et références/sigils-personnalisés.md.
Carte de référence
Lisez uniquement les fichiers nécessaires à la tâche en cours :
- Bases du nœud embarqué, Ratatoskr vs yggstack, architecture, portée : références/aperçu.md
ratatoskr.New,ConfigObj, cycle de vie, sécurité des threads, méthodes racine, erreurs, instantané : références/api-racine.md- TCP, UDP,
DialContext,Listen,ListenPacket, client/serveur HTTP, multicast/admin, points de test : références/réseautage.md - Pairs statiques, gestionnaire de pairs, SOCKS5, résolveur, redirection de ports : références/pairs-socks-redirection.md
- NodeInfo,
Ask/AskAddr, sigils intégrés avec limites exactes : références/nodeinfo-sigils.md - Accès typé et création/câblage de vos propres sigils (pas de
map[string]anybrut) : références/sigils-personnalisés.md - Modèles client/serveur et intégrations de frameworks (net/http, fasthttp, gRPC, pont gnet) : références/intégrations.md
- Zones avancées/en cours (probe, settings) et modèles d'application CLI/exemple : références/avancés-et-exemples.md
- Recettes d'application prêtes à adapter : références/recettes.md
Erreurs courantes
| Erreur | Correction |
|---|---|
| Démarrer un démon Yggdrasil externe pour une application embarquée | Utilisez ratatoskr.New ; il exécute une pile réseau gVisor en espace utilisateur. |
Recommander yggstack pour l'intégration bibliothèque | yggstack est un binaire utilisateur final. Utilisez Ratatoskr pour le contrôle via l'API Go. |
Définir à la fois cfg.Config.Peers et ConfigObj.Peers | Choisissez les pairs statiques ou le gestionnaire de pairs ; jamais les deux → ErrPeersConflict. |
Passer Ctx mais sauter Close (ou vice versa) | Faites les deux : l'annulation déclenche l'arrêt, Close libère les ressources. |
| Construire des URL sans crochets IPv6 | Utilisez fmt.Sprintf("http://[%s]:%d", ip, port). |
Créer ninfo.New pour des requêtes de base | Utilisez node.Ask / node.AskAddr ; l'objet racine construit déjà ninfo. |
| Assembler ou enregistrer des sigils dynamiquement à l'exécution | Les sigils sont assemblés strictement dans le code ; les clés en double ou écrasantes sont des erreurs dures par conception, pas des fusions silencieuses. Publiez via ConfigObj.Sigils ; lisez vos propres clés depuis res.Node.Extra. |
Utiliser UnsafeCore() / mod/probe / mod/settings par défaut | Restez sur l'API racine ; ceux-ci sont avancés ou en cours de développement. |
| Coder en dur une version de Go depuis le README | Lisez le go.mod actif de la version de module sélectionnée. |
Validation
Gardez SKILL.md comme couche de navigation et mettez les détails lourds de l'API dans
références/. Testez les changements par anticipation par rapport aux scénarios dans
évaluations/évaluations.json avant de publier.