ソースを参照

Add Spartan protocol support, fix issue where connections were not closing

Billy Barrow 1 年間 前
コミット
71cabb44ea
4 ファイル変更50 行追加9 行削除
  1. 18 4
      config
  2. 3 0
      src/configuration.vala
  3. 20 0
      src/header_reader.vala
  4. 9 5
      src/server.vala

+ 18 - 4
config

@@ -10,13 +10,27 @@ HTTP billy.barrow.nz 80 {
     185.112.145.195 80
 }
 
+
 WELL-KNOWN billy.barrow.nz 80 {
     192.168.1.235 80
 }
 
-XMPP im.barrow.nz 5222 FASTEST {
-    192.168.1.232 443
-    192.168.1.233 443
-    192.168.1.235 443
+XMPP im.barrow.nz 5222 {
     185.112.144.131 5222
 }
+
+TLS im.barrow.nz 443 {
+    185.112.144.131 443
+}
+
+TLS smol.pub 1965 {
+    213.219.38.200 1965
+}
+
+TLS spartan.mozz.us 1965 {
+    174.138.124.169 1965
+}
+
+SPARTAN mozz.us 300 {
+    174.138.124.169 300
+}

+ 3 - 0
src/configuration.vala

@@ -64,6 +64,9 @@ namespace Astrogate {
                     case "XMPP":
                         entry.protocol = ConnectionType.XMPP;
                         break;
+                    case "SPARTAN":
+                        entry.protocol = ConnectionType.SPARTAN;
+                        break;
                     default:
                         throw new ConfigurationFormatError.UNRECOGNISED_PROTOCOL(@"Unrecognised protocol type $(type)");
                 }

+ 20 - 0
src/header_reader.vala

@@ -9,6 +9,7 @@ namespace Astrogate {
         DIAL,
         HTTP_WELL_KNOWN,
         XMPP,
+        SPARTAN,
     }
  
     public class HeaderReader {
@@ -56,6 +57,14 @@ namespace Astrogate {
                 return ConnectionType.XMPP;
             }
 
+            // Spartan
+            var header = str_data.split("\r\n", 2);
+            var header_parts = header[0].split(" ");
+            if(header_parts[1].has_prefix("/") && int.try_parse(header_parts[2])) {
+                return ConnectionType.SPARTAN;
+            }
+
+
             return ConnectionType.INVALID;
         }
 
@@ -70,11 +79,22 @@ namespace Astrogate {
                     return read_tls_sni(data);
                 case ConnectionType.XMPP:
                     return read_xmpp_stream_to(data);
+                case ConnectionType.SPARTAN:
+                    return read_spartan_host(data);
                 default:
                     return null;
             }
         }
 
+        public static string? read_spartan_host(BinaryData data) {
+            var header = data.to_raw_string().split("\r\n", 2);
+            var header_parts = header[0].split(" ");
+            if(header_parts[1].has_prefix("/") && int.try_parse(header_parts[2])) {
+                return header_parts[0];
+            }
+            return null;
+        }
+
         public static string? read_xmpp_stream_to(BinaryData data) {
             var str_data = data.to_raw_string();
             if(str_data.contains("<stream:stream") && str_data.contains("xmlns:stream='http://etherx.jabber.org/streams'") && str_data.contains(">")) {

+ 9 - 5
src/server.vala

@@ -37,14 +37,14 @@ namespace Astrogate {
     private async void handle_connection(SocketConnection connection) {
         try {
             var port = ((InetSocketAddress)connection.get_local_address()).port;
-            print(@"New connection (port $(port))\n");
             var buffer = yield HeaderReader.read_sample(connection.input_stream);
             var type = HeaderReader.determine_type(buffer);
             if(type == ConnectionType.INVALID) {
-                print("Invalid connection type.\n");
+                print(@"Could not determine type of incoming connection on port $port.\n");
                 yield connection.close_async();
                 return;
             }
+            print(@"New $type connection on port $(port)\n");
             var name = HeaderReader.read_name(buffer, type);
             if(name != null) {
                 var entry = get_entry(type, (uint16)port, name);
@@ -92,8 +92,9 @@ namespace Astrogate {
         yield proxy.output_stream.write_async(initial_buffer.to_array(), 0);
         yield proxy.output_stream.flush_async(0);
 
-        proxy.output_stream.splice_async.begin(connection.input_stream, OutputStreamSpliceFlags.CLOSE_SOURCE | OutputStreamSpliceFlags.CLOSE_TARGET, 0);
-        connection.output_stream.splice_async.begin(proxy.input_stream, OutputStreamSpliceFlags.CLOSE_SOURCE | OutputStreamSpliceFlags.CLOSE_TARGET, 0);
+        var cancellation_token = new Cancellable();
+        proxy.output_stream.splice_async.begin(connection.input_stream, OutputStreamSpliceFlags.CLOSE_SOURCE | OutputStreamSpliceFlags.CLOSE_TARGET, 0, cancellation_token, () => cancellation_token.cancel());
+        connection.output_stream.splice_async.begin(proxy.input_stream, OutputStreamSpliceFlags.CLOSE_SOURCE | OutputStreamSpliceFlags.CLOSE_TARGET, 0, cancellation_token, () => cancellation_token.cancel());
     }
 
     private async SocketConnection connect_round_robin(ConfigurationItem entry) throws Error {
@@ -141,7 +142,7 @@ namespace Astrogate {
                 return;
             }
             catch(Error e) {
-                print(@"Failure during connect-first (aka. fastest), could not connect to peer: $(e.message)\n");
+                print(@"Failure during connect-first (aka. fastest): $(e.message)\n");
             }
             in_flight--;
             connect_first_responder.callback();
@@ -156,6 +157,9 @@ namespace Astrogate {
             print(@"In flight requests: $(in_flight)\n");
             yield;
         }
+        if(connection == null) {
+            throw new IOError.HOST_UNREACHABLE("Could not reach any specified forwarding host");
+        }
         cancel_token.cancel();
         return connection;
     }