{"id":41363586,"url":"https://github.com/platform9/cnxmd","last_synced_at":"2026-01-23T08:10:43.660Z","repository":{"id":65518282,"uuid":"160271576","full_name":"platform9/cnxmd","owner":"platform9","description":"connection metadata protocol","archived":false,"fork":false,"pushed_at":"2018-12-28T07:57:51.000Z","size":12,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":44,"default_branch":"master","last_synced_at":"2023-08-18T15:38:58.195Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/platform9.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-12-04T00:21:25.000Z","updated_at":"2019-05-02T21:49:33.000Z","dependencies_parsed_at":"2023-01-27T00:30:25.163Z","dependency_job_id":null,"html_url":"https://github.com/platform9/cnxmd","commit_stats":null,"previous_names":[],"tags_count":0,"template":null,"template_full_name":null,"purl":"pkg:github/platform9/cnxmd","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/platform9%2Fcnxmd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/platform9%2Fcnxmd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/platform9%2Fcnxmd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/platform9%2Fcnxmd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/platform9","download_url":"https://codeload.github.com/platform9/cnxmd/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/platform9%2Fcnxmd/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28684017,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-23T05:48:07.525Z","status":"ssl_error","status_checked_at":"2026-01-23T05:48:07.129Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":[],"created_at":"2026-01-23T08:10:41.602Z","updated_at":"2026-01-23T08:10:43.654Z","avatar_url":"https://github.com/platform9.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Connection Metadata (CNXMD) Protocol\n\nThe CNXMD protocol defines a header that a client proxy can send to a\nCNXMD-aware server proxy in order to pass arbitrary key-value pairs containing\ninformation about the connection to be proxied. It has similarities to\nthe [PROXY protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)\nand could be viewed as a generalization of it.\n\n## Typical Flow\n\n- A client attempts to communicate with a destination server.\n- Between the client and server reside a client-side proxy and a server-side proxy.\n- The client connects to the client-side proxy.\n- The client-side proxy connects to the server-side proxy.\n- The client-side proxy sends a CNXMD header to the server-side proxy. The header contains a list of KV pairs.\n- The server-side proxy locates the destination server, possibly using information contained in the KV pairs.\n- The client-side proxy pipes the connection from the client.\n- The server-side proxy pipes the connection to the destination server.\n- The client and server can now communicate.\n\n## Specification\n\nThe CNXMD header is composed of a sequence of newline ('\\n') terminated lines.\nThe first line must be \"CONNECTION_METADATA/1.1\\n\"\nWhat follows is zero or more key-value pairs formatted as \"key=value\\n\"\nAll characters following the '=' character are interpreted as belonging to the value.\nThe header is terminated with the blank line \"\\n\"\nThe specification does not define a maximum line length or number of lines.\nHowever, specific implementations may impose their own limits.\n\nExample:\n```\nCONNECTION_METADATA/1.1\\n\nfoo=bar\\n\njane=john=jack\\n\n\\n\n```\nThe above header sends the key-values: {\"foo\":\"bar\", \"jane\":\"john=jack\"}\n\n## Use case(s)\n\nOne use case is to augment the\n[Server Name Indication](https://tools.ietf.org/html/rfc6066#section-3) feature\nof TLS. A server-side TLS proxy can use the Server Name (SN) specified in the SNI\nheader to locate the correct destination server.\n\nThere may be situations where a TLS client does not set the Server Name correctly,\nor does not set it at all, making it impossible for the TLS proxy to route\nthe connection.\n\nThis problem can be solved by a combination of:\n1. inserting a client-side CNXMD proxy between the client and TLS proxy\n2. enhancing the TLS proxy to recognize the CNXMD header as an alternative\nto the SNI header for routing purposes\n\nAssuming the client-side proxy knows the appropriate SN for connections\ninitiated by the client, it inserts the SN into the CNXMD header. The SN can\nbe specified using a CNXMD kv entry (for e.g. using a key named \"host\").\nUpon detecting a CNXMD header with the correct key, the TLS proxy removes\nthe header from the TLS stream and proxies the connection to the appropriate\ndestination server.\n\n## Repo contents\nThis repo contains a go library with two useful functions:\n- Parse() attempts to decode a CNXMD header from a byte slice. If successful,\nit returns the length of the header and a map containing the KV pairs.\n- ServeClientProxy() implements a client-side proxy. A CNXMD header is generated\nfrom the supplied map containing KV pairs.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplatform9%2Fcnxmd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fplatform9%2Fcnxmd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplatform9%2Fcnxmd/lists"}