RFC 3089
A SOCKS-based IPv6/IPv4 Gateway Mechanism
RFC 3089: A SOCKS-based IPv6/IPv4 Gateway Mechanism π¦
Title block tea β
- Number: 3089
- Author: H. Kitamura, NEC Corporation π
- Category: Informational π
- Date: April 2001 πΈ
- Obsoletes / Updates: the header doesn't list anything this one obsoletes or updates, so it stands on its own π«Ά
Status of This Memo β¨
okay so first things first, this memo is giving "information only" energy π It is not a standard. It's here to share info with the Internet community. Distribution is totally unlimited, so share away bestie π
Copyright Notice π
Copyright (C) The Internet Society (2001). All Rights Reserved.
Abstract π¦
okay this doc is about a SOCKS-based IPv6/IPv4 gateway mechanism that lets IPv6 nodes and IPv4 nodes talk to each other super smoothly π«Ά
It's built on the SOCKS protocol [SOCKSv5] β¨ The trick is to apply SOCKS to these mixed-protocol conversations and have the SOCKS server (the "application layer" thing) relay two "terminated" connections, one IPv4 and one IPv6. That's how the gateway gets made π₯
And the best part? No brand new protocols needed π So everyone gets the same vibe SOCKS already gives, and the mixed-protocol chats look and feel the same. None of the conveniences or features of current communications get sacrificed. Iconic, honestly π
1. Introduction πΈ
okay so the SOCKS-based IPv6/IPv4 gateway works by relaying two "terminated" IPv4 and IPv6 connections at the "application layer" (aka the SOCKS server) π§ It inherits its traits from two places: the application-layer connection relay thing, and the native SOCKS mechanism. Main character lineage, no cap π
2. Basic SOCKS-based Gateway Mechanism π
Figure 1 shows the basic setup, so let's look at it together π
Client C Gateway G Destination D
+-----------+ (Server)
|Application|
+-->+===========+ +-------------+ +-----------+
same-+ |*SOCKS Lib*| | *Gateway* | |Application|
API +-->+===========+ +=====---=====+ +-----------+
| Socket DNS| | Socket DNS | | Socket DNS|
+-----------+ +-------------+ +-----------+
| [ IPv X ] | |[IPvX]|(IPvY)| | ( IPv Y ) |
+-----------+ +-------------+ +-----------+
|Network I/F| | Network I/F | |Network I/F|
+-----+-----+ +---+-----+---+ +-----+-----+
| | | |
+============+ +------------+
socksified normal
connection connection
(ctrl)+data data only
Fig. 1 Basic SOCKS-based Gateway Mechanism
So in this picture, Client C starts the conversation with Destination D π Two new building blocks make this work π«Ά
The first one is Socks Lib π It lives on the client side (Client C), and yes, the process of adding it is called "socksifying" π It sits between the application layer and the socket layer, and it can swap out an app's socket APIs and DNS name resolving APIs (like gethostbyname(), getaddrinfo() etc.) π It also has a mapping table for a "DNS name resolving delegation" feature, which we'll get to. Every socksified app gets its own Socks Lib, so it's a whole personal-stylist situation π
The second one is Gateway π₯ It's installed on the dual stack node (Gateway G) that runs both IPv6 and IPv4. It's an enhanced SOCKS server that can relay between any combo of protocols, so Client C (IPvX) and Destination D (IPvY) can be on any mix π¦ When Socks Lib asks for a relay, a Gateway process (or thread) gets spawned off the parent Gateway to handle that particular connection π§
There are four possible combos of IPvX and IPvY in this mechanism π
type C ------ G ------ D
[IPvX] (IPvY)
A IPv4 IPv4 homogeneous (normal SOCKS)
B IPv4 IPv6 * heterogeneous *
C IPv6 IPv4 * heterogeneous *
D IPv6 IPv6 homogeneous
Type A is already handled by normal SOCKS π Types B and C are the main event for this gateway mechanism, since they're the heterogeneous ones π₯ Type D can come from a natural extension of SOCKS, since it's homogeneous and all the same protocol β¨
Here's the thing: Socks Lib talks to the Gateway using the SOCKS protocol [SOCKSv5], so that link between Client C and Gateway G is a special one called a "socksified connection" π¦ It can carry control info too, not just data. For example, it can pass along the location information of Destination D π
The link between Gateway G and Destination D is a normal connection πΈ It doesn't get socksified. The server app running on Destination D doesn't even notice Client C exists π It thinks its peer is Gateway G, not Client C. Ghosting, but make it networking π
No new protocols get added to SOCKS [SOCKSv5] to pull this off π«Ά
Note to self: the next two bits are the important gotchas, so don't skip them π₯
Packet Size Adjustment π§
Okay so the IPv6 header length is different from the IPv4 header length π That means you have to think about packet size adjustment in mixed-protocol communications π If you skip that, the packet size could go over the network's MTU, and that is NOT a vibe π
Here's the good news though π In the SOCKS-based IPv6/IPv4 gateway mechanism, packets never exceed the MTU. That's because the mechanism relays two "terminated" connections at the "application layer" π¦ The relayed data is just a simple data stream as far as the application is concerned, so the packet size naturally gets adjusted on each side of each relayed connection β¨
Authenticated Relay π
SOCKS was originally built for firewall systems, and it comes with lots of authentication methods π So the relayed connections can be authenticated using the native SOCKS authentication methods. Secure and slay π
3. DNS Name Resolving Procedure β¨
okay so every communication app needs the destination's IP address before it can even start talking π but here's the tea: it's theoretically impossible for heterogeneous (IPv4 + IPv6 mixed) communications to get correct info, bc an existing IPv4 app can't deal with an IPv6 address π it only has a 4-byte space to store an IP address, and an IPv6 address just doesn't fit. that's the critical problem, and it's caused by the different address lengths π
so to fix it, the SOCKS-based IPv6/IPv4 gateway mechanism uses a feature called "DNS name resolving delegation" π«Ά the source node (Client C) hands its DNS name resolving work over to the relay server (Gateway G). the relay is a dual stack node (IPv4 and IPv6 both), so it can make DNS queries for any address family without causing problems. the best part? you don't have to modify the existing DNS mechanism at all π
this feature works when you give it a destination logical host name (FQDN) and also when you give it a literal (numerical) IP address. the literal case is handled pretty much the same way as the FQDN case π¦ and since a literal IPv6 address has colons (":") in it, an IPv4 application reads it as an FQDN, not a literal IPv4 address π§
the SOCKS protocol spec [SOCKSv5] says IPv4 address, IPv6 address, and DOMAINNAME (FQDN) can all show up in the ATYP (address type) field of the SOCKS protocol format β¨ in the "DNS name resolving delegation" feature, the DOMAINNAME (FQDN) value is what goes in the ATYP field. the FQDN gets sent from Client C to Gateway G to tell it where Destination D is π
now, to get around that critical problem, the feature brings in an appropriate "fake IP" address πΈ it's used as a virtual destination IP address for a socksified application. there's also a mapping table in the Socks Lib (at Client C) that keeps track of which "fake IP" goes with which "FQDN" π you look up the FQDN using the "fake IP" as the key. and the mapping table is local, so it's independent from other applications and their *Socks Lib*s π₯
the transparency for apps is maintained, which is so iconic π nothing special is needed except socksifying the applications. since the DNS name resolving APIs get replaced by the Socks Lib, the "DNS name resolving delegation" just happens internally whenever an app calls the DNS name resolving APIs in its ordinary way π
the "DNS name resolving delegation" only happens when FQDN information is used in the ATYP (address type) field of the SOCKS command, so it's mandatory for heterogeneous communications. how you use FQDN in the ATYP field depends on the configuration and implementation of the SOCKS protocol. to keep things simple, this doc only discusses the case where FQDN is used in the ATYP field π«Ά
here's the detailed internal procedure for "DNS name resolving delegation", plus the address mapping management stuff π
- an application on the source node (Client C) tries to get the IP address of the destination node (Destination D) by calling the DNS name resolving function (e.g.,
gethostbyname()). the logical host name ("FQDN") of Destination D gets passed to the application's Socks Lib as an argument of the called APIs π - since the Socks Lib has replaced those DNS name resolving APIs, the real DNS name resolving APIs are not called here π
the "FQDN" is just registered into a mapping table in the Socks Lib. then a "fake IP" address gets picked from a reserved special IP address space that's never used in real communications (e.g.,
0.0.0.x) and replied to the application π the "fake IP" address family must be suitable for what the application asked for. so it must be in the same address family as Client C, even if Destination D is a different family π¦ once the "fake IP" is registered in the mapping table as a pair with the "FQDN", it gets replied to the application β¨ - the application receives the "fake IP" address and prepares a "socket" π§ the "fake IP" address info is used as an element of the "socket". then the application calls socket APIs (e.g.,
connect()) to start communicating, with the "socket" as an argument of those APIs π - since the Socks Lib has replaced those socket APIs, the real socket function is not called π the IP address info of the socket gets checked. if the address is in the special address space for fake addresses, the matching registered "FQDN" for that "fake IP" gets pulled from the mapping table π
- the "FQDN" gets transferred to the Gateway on the relay server (Gateway G) using the SOCKS command that matches the called socket API (e.g., for
connect(), the CONNECT command is used) π - finally, the real DNS name resolving API (e.g.,
getaddrinfo()) is called at the Gateway π₯ the "FQDN" it received via the SOCKS protocol is used as an argument of those APIs π - the Gateway gets the "real IP" address from a DNS server and creates a "socket" β¨ the "real IP" info is used as an element of that socket πΈ
- the Gateway calls socket APIs (e.g.,
connect()) to communicate with Destination D π the "socket" is the argument of those APIs π¦
okay but the catch π¬ with this feature, DNS name resolving failures get detected incorrectly at the source node (Client C). they show up as connection-establishment failures instead. kinda sus, bestie π
(restrictions on where the "fake IP" address can be used, etc., are in Section 5 π)
Operations for Address Management (reservation, mapping etc.)
the SOCKS-based gateway mechanism doesn't need a wide global address space reserved for address mapping, and it doesn't need complex address allocation or garbage-collection mechanisms either π
the address management ops are handled at the Socks Lib using the fake IP address and the mapping table for DNS name resolving delegation π§ since the mapping table is prepared in each application, it's locally closed and independent of other applications. so it's easy to manage, and you don't need to reserve a wide global address space π
4. Multiple Chained Relay Mechanism (Advanced usage) π¦
the SOCKS-based gateway mechanism is super flexible and can support multiple chained relay topologies π with it, mixed IPv4 and IPv6 communication topologies of all kinds are doable β¨
Figure 2 shows the structure of the multiple chained relay mechanism π
Client C Gateway G1 Gateway G2 Destination D
+-----------+ (Server 1) (Server 2)
|Application|
+===========+ +-------------+ +-------------+ +-----------+
|*SOCKS Lib*| | *Gateway1* | | *Gateway2* | |Application|
+===========+ +=====---=====+ +=====---=====+ +-----------+
| Socket DNS| | Socket DNS | | Socket DNS | | Socket DNS|
+-----------+ +-------------+ +-------------+ +-----------+
| [ IPv X ] | |[IPvX]|(IPvY)| |(IPvY)|{IPvZ}| | { IPv Z } |
+-----------+ +-------------+ +-------------+ +-----------+
|Network I/F| | Network I/F | | Network I/F | |Network I/F|
+-----+-----+ +---+-----+---+ +---+-----+---+ +-----+-----+
| | | | | |
+============+ +==========+ +------------+
socksified socksified normal
connection connection connection
(ctrl)+data (ctrl)+data data only
Fig. 2 Multiple Chained Relay Mechanism
in this figure, the source node (Client C) starts communicating with the destination (Destination D) π§ under the hood, the connection gets replaced with three connections, and they're relayed at two relay servers (Gateway G1 and G2) π the Gateway has the same type of functions as the Socks Lib. by enabling the Socks Lib functions at Gateway1 on the first relay server (Gateway G1), the multiple chained relay topology gets accomplished π
there's no limit on how many relay operations can happen between the source node and the final destination node π you can have more than two intermediate relay servers. to keep the explanation simple, this doc shows a twice-relayed topology π«Ά
ngl, multiple chained relay is more complex than a one-time relay and adds complexity π΅βπ« so it's recommended that multiple chained relay communication only be used when it's necessary for some reason (e.g., usable protocols or topologies are limited by routers etc.) π
5. Applicability statement β¨
okay so bestie, the SOCKS-based gateway mechanism is all about socksifying applications so they can talk across IPv4 and IPv6 π¦. You install Socks Lib, and that's it. No rewriting your source code and recompiling, no cap π . It works by changing the linking order of the dynamic link libraries, so the SOCKS library gets loaded before the normal socket and DNS name resolving libraries. the way that just slides in π«Ά
The mechanism also doesn't touch the DNS system at all πΈ. The DNS name resolving at Client C gets handed off to the dual stack node, Gateway G. Main character energy for Gateway G, ngl π
Apart from socksification, the SOCKS-based gateway mechanism has three kinds of constraints. Let's go through them π
- Essential constraints π
These come from the address length difference between IPv4 and IPv6.
Functions that return an IP address (like getpeername() and getsockname()) can not give back the correct IP address. However, they can still give back a suitable port value, because IPv4 and IPv6 use the same size port space, and the right port information gets carried over by the SOCKS protocol β¨
- Constraints of the SOCKS mechanism π
The current SOCKS system can not socksify all of the tricky applications that use weird special methods to create their connections. So the SOCKS-based gateway mechanism can not be applied to those apps. not me being sad about it π
- Constraints to deal with the fake address π§
The fake address has to be treated as a temporary value inside the application. It's used as a key in the mapping table for the "DNS name resolving delegation" feature. Once the application finishes and the mapping table disappears, the fake address info has to be released too, bestie π«Ά
Even if it does get saved permanently (say, as a bookmark), serious problems won't happen π. The saved fake address will just become useless. Fake addresses come from a reserved special IP address space that is never used in real communications (for example 0.0.0.x), so that info is useless to normal communication applications. And these cases should be rare anyway, because most apps save the FQDN (not the fake IP address) to their bookmarks, etc. iykyk π
5.1 Native SOCKS mechanism considerations
okay so the SOCKS-based IPv6/IPv4 gateway mechanism inherits its characteristics from the native SOCKS mechanism π. That means the native SOCKS considerations apply here too, and this section covers them β¨
SOCKSv5 has three commands: CONNECT, BIND and UDP ASSOCIATE. All three can be used with the SOCKS-based IPv6/IPv4 gateway mechanism π
This document is mostly written assuming you're using the CONNECT command π . It's the main, most frequently used command in SOCKS, and since CONNECT doesn't have clear weak points, you can use it freely without extra considerations. literally the easiest one π
BIND and UDP ASSOCIATE do have weak points, though π So when you use either of them with the mechanism, you have to keep those points in mind.
The BIND command is basically designed to support reverse-channel rendezvous for FTP-type applications. So general uses of BIND may cause problems π¬
The UDP ASSOCIATE command is basically designed for simple UDP applications (for example, archie). It isn't general enough to support the large class of applications that use both TCP and UDP π
6. Security Considerations π
okay this part is SERIOUS bestie π Since the SOCKS-based IPv6/IPv4 gateway mechanism is built on SOCKSv5, its security features match SOCKSv5's. You can read all about it in the Security Considerations section of the SOCKS Protocol Version 5 [SOCKSv5] π
The mechanism works by relaying two "terminated" connections at the "application layer". End-to-end security is kept on each of the relayed connections: between Client C and Gateway G, and between Gateway G and Destination D. But the mechanism does not provide total end-to-end security relay between the original source (Client C) and the final destination (Destination D) β οΈ
bestie, read that last part twice. The security is per-hop, not end-to-end across the whole path. Don't assume the whole path is protected just because each leg is π₯Ί
Appendix A. Implementations π§
okay so right now there are two independent implementations of the SOCKS-based IPv6/IPv4 gateway mechanism π Both are open to the public, so you can go check them out π
One is NEC's implementation. Its source codes are available at the following URL:
http://www.socks.nec.com/
The other is Fujitsu Lab.'s implementation, which is called "SOCKS64". Its source codes are available at the following URL:
ftp://ftp.kame.net/pub/kame/misc/socks64-...
References π
[SOCKSv5] Leech, M., Ganis, M., Lee, Y., Kuris, R., Koblas, D. and
L. Jones, "SOCKS Protocol V5", RFC 1928, April 1996.
[TRANSMECH] Gilligan, R. and E. Nordmark, "Transition Mechanisms for
IPv6 Hosts and Routers", RFC 2893, August 2000.
[IPv6] Deering, S. and R. Hinden, "Internet Protocol, Version 6
(IPv6) Specification", RFC 2460, December 1998.
[INET99] H. Kitamura, "Entering the IPv6 communication world by
the SOCKS-based IPv6/IPv4 Translator", in Proceedings of
INET99, July 1999.
Author's Address π
Hiroshi Kitamura
NEC Corporation
Development Laboratories
(Igarashi Building 4F) 11-5, Shibaura 2-Chome,
Minato-Ku, Tokyo 108-8557, JAPAN
Phone: +81 (3) 5476-1071
Fax: +81 (3) 5476-1005
EMail: kitamura@da.jp.nec.com
Full Copyright Statement βοΈ
Copyright (C) The Internet Society (2001). All Rights Reserved.
This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English.
The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns.
This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Acknowledgement π«Ά
Funding for the RFC Editor function is currently provided by the Internet Society π
π¦ where this page comes from
- ietf: rfc3089 2001-04
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms