@@ -19,7 +19,9 @@ enum Type {
1919 SCTP (132 , 16 , "sctp" ),
2020 UTP (301 , 0 , "utp" ),
2121 UDT (302 , 0 , "udt" ),
22+ UNIX (400 , LENGTH_PREFIXED_VAR_SIZE , "unix" ),
2223 IPFS (421 , LENGTH_PREFIXED_VAR_SIZE , "ipfs" ),
24+ QUIC (460 , 0 , "quic" ),
2325 HTTPS (443 , 0 , "https" ),
2426 HTTP (480 , 0 , "http" ),
2527 ONION (444 , 80 , "onion" );
@@ -52,6 +54,10 @@ public void appendCode(OutputStream out) throws IOException {
5254 out .write (type .encoded );
5355 }
5456
57+ public boolean isTerminal () {
58+ return type == Type .UNIX ;
59+ }
60+
5561 public int size () {
5662 return type .size ;
5763 }
@@ -95,29 +101,43 @@ public byte[] addressToBytes(String addr) {
95101 bout .write (varint );
96102 bout .write (hashBytes );
97103 return bout .toByteArray ();
98- case ONION :
104+ case ONION : {
99105 String [] split = addr .split (":" );
100106 if (split .length != 2 )
101- throw new IllegalStateException ("Onion address needs a port: " + addr );
107+ throw new IllegalStateException ("Onion address needs a port: " + addr );
102108
103109 // onion address without the ".onion" substring
104110 if (split [0 ].length () != 16 )
105- throw new IllegalStateException ("failed to parse " + name ()+ " addr: " + addr + " not a Tor onion address." );
111+ throw new IllegalStateException ("failed to parse " + name () + " addr: " + addr + " not a Tor onion address." );
106112
107113 byte [] onionHostBytes = Base32 .decode (split [0 ].toUpperCase ());
108114 int port = Integer .parseInt (split [1 ]);
109115 if (port > 65535 )
110- throw new IllegalStateException ("Port is > 65535: " + port );
116+ throw new IllegalStateException ("Port is > 65535: " + port );
111117
112118 if (port < 1 )
113- throw new IllegalStateException ("Port is < 1: " + port );
119+ throw new IllegalStateException ("Port is < 1: " + port );
114120
115121 ByteArrayOutputStream b = new ByteArrayOutputStream ();
116122 DataOutputStream dout = new DataOutputStream (b );
117123 dout .write (onionHostBytes );
118124 dout .writeShort (port );
119125 dout .flush ();
120126 return b .toByteArray ();
127+ }
128+ case UNIX : {
129+ if (addr .startsWith ("/" ))
130+ addr = addr .substring (1 );
131+ byte [] path = addr .getBytes ();
132+ ByteArrayOutputStream b = new ByteArrayOutputStream ();
133+ DataOutputStream dout = new DataOutputStream (b );
134+ byte [] length = new byte [(32 - Integer .numberOfLeadingZeros (path .length )+6 )/7 ];
135+ putUvarint (length , path .length );
136+ dout .write (length );
137+ dout .write (path );
138+ dout .flush ();
139+ return b .toByteArray ();
140+ }
121141 }
122142 } catch (IOException e ) {
123143 throw new RuntimeException (e );
@@ -131,11 +151,11 @@ public String readAddress(InputStream in) throws IOException {
131151 switch (type ) {
132152 case IP4 :
133153 buf = new byte [sizeForAddress ];
134- in . read (buf );
154+ read (in , buf );
135155 return Inet4Address .getByAddress (buf ).toString ().substring (1 );
136156 case IP6 :
137157 buf = new byte [sizeForAddress ];
138- in . read (buf );
158+ read (in , buf );
139159 return Inet6Address .getByAddress (buf ).toString ().substring (1 );
140160 case TCP :
141161 case UDP :
@@ -144,15 +164,32 @@ public String readAddress(InputStream in) throws IOException {
144164 return Integer .toString ((in .read () << 8 ) | (in .read ()));
145165 case IPFS :
146166 buf = new byte [sizeForAddress ];
147- in . read (buf );
167+ read (in , buf );
148168 return Cid .cast (buf ).toString ();
149169 case ONION :
150170 byte [] host = new byte [10 ];
151- in . read (host );
171+ read (in , host );
152172 String port = Integer .toString ((in .read () << 8 ) | (in .read ()));
153173 return Base32 .encode (host )+":" +port ;
174+ case UNIX :
175+ buf = new byte [sizeForAddress ];
176+ read (in , buf );
177+ return new String (buf );
178+ }
179+ throw new IllegalStateException ("Unimplemented protocol type: " +type .name );
180+ }
181+
182+ private static void read (InputStream in , byte [] b ) throws IOException {
183+ read (in , b , 0 , b .length );
184+ }
185+
186+ private static void read (InputStream in , byte [] b , int offset , int len ) throws IOException {
187+ int total =0 , r =0 ;
188+ while (total < len && r != -1 ) {
189+ r = in .read (b , offset + total , len - total );
190+ if (r >=0 )
191+ total += r ;
154192 }
155- throw new IllegalStateException ("Unimplemented protocl type: " +type .name );
156193 }
157194
158195 public int sizeForAddress (InputStream in ) throws IOException {
0 commit comments