PowerDNS JSON handler
This commit is contained in:
parent
a23049e449
commit
d101277c9a
4 changed files with 107 additions and 12 deletions
|
|
@ -1,4 +1,3 @@
|
||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace pdns_dhcp.PowerDns;
|
namespace pdns_dhcp.PowerDns;
|
||||||
|
|
@ -8,19 +7,21 @@ public interface IMethod;
|
||||||
[JsonPolymorphic(TypeDiscriminatorPropertyName = "method")]
|
[JsonPolymorphic(TypeDiscriminatorPropertyName = "method")]
|
||||||
[JsonDerivedType(typeof(InitializeMethod), "initialize")]
|
[JsonDerivedType(typeof(InitializeMethod), "initialize")]
|
||||||
[JsonDerivedType(typeof(LookupMethod), "lookup")]
|
[JsonDerivedType(typeof(LookupMethod), "lookup")]
|
||||||
public abstract class Method
|
public class Method;
|
||||||
{
|
|
||||||
[JsonExtensionData]
|
|
||||||
public Dictionary<string, JsonElement> ExtensionData { get; } = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class Method<TSelf> : Method where TSelf : Method<TSelf>, IMethod;
|
[JsonSerializable(typeof(Method)), JsonSourceGenerationOptions(
|
||||||
|
GenerationMode = JsonSourceGenerationMode.Metadata,
|
||||||
|
NumberHandling = JsonNumberHandling.AllowReadingFromString,
|
||||||
|
UseStringEnumConverter = true
|
||||||
|
)]
|
||||||
|
internal partial class MethodContext : JsonSerializerContext;
|
||||||
|
|
||||||
public abstract class Method<TSelf, TParam>(TParam parameters) : Method<TSelf> where TSelf : Method<TSelf, TParam>, IMethod
|
public abstract class Method<TParam>(TParam parameters) : Method
|
||||||
|
where TParam : MethodParameters
|
||||||
{
|
{
|
||||||
public TParam Parameters => parameters;
|
public TParam Parameters => parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class InitializeMethod : Method<InitializeMethod>, IMethod;
|
public class InitializeMethod(InitializeMethodParameters parameters) : Method<InitializeMethodParameters>(parameters), IMethod;
|
||||||
|
|
||||||
public class LookupMethod : Method<LookupMethod>, IMethod;
|
public class LookupMethod(LookupMethodParameters parameters) : Method<LookupMethodParameters>(parameters), IMethod;
|
||||||
|
|
|
||||||
26
src/pdns-dhcp/PowerDns/Parameters.cs
Normal file
26
src/pdns-dhcp/PowerDns/Parameters.cs
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace pdns_dhcp.PowerDns;
|
||||||
|
|
||||||
|
public record class Parameters;
|
||||||
|
|
||||||
|
public record class MethodParameters : Parameters
|
||||||
|
{
|
||||||
|
[JsonExtensionData]
|
||||||
|
public Dictionary<string, JsonElement> AdditionalProperties { get; set; } = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public record class InitializeMethodParameters(
|
||||||
|
[property: JsonPropertyName("command")] string Command,
|
||||||
|
[property: JsonPropertyName("timeout")] int Timeout
|
||||||
|
) : MethodParameters;
|
||||||
|
|
||||||
|
public record class LookupMethodParameters(
|
||||||
|
[property: JsonPropertyName("qtype")] string Qtype,
|
||||||
|
[property: JsonPropertyName("qname")] string Qname,
|
||||||
|
[property: JsonPropertyName("remote")] string Remote,
|
||||||
|
[property: JsonPropertyName("local")] string Local,
|
||||||
|
[property: JsonPropertyName("real-remote")] string RealRemote,
|
||||||
|
[property: JsonPropertyName("zone-id")] int ZoneId
|
||||||
|
) : MethodParameters;
|
||||||
|
|
@ -15,6 +15,7 @@ public class PowerDnsHandler : ConnectionHandler
|
||||||
JsonReaderState state = default;
|
JsonReaderState state = default;
|
||||||
using ArrayPoolBufferWriter<byte> json = new();
|
using ArrayPoolBufferWriter<byte> json = new();
|
||||||
using ArrayPoolBufferWriter<byte> buffer = new();
|
using ArrayPoolBufferWriter<byte> buffer = new();
|
||||||
|
using var writer = connection.Transport.Output.AsStream();
|
||||||
while (!connection.ConnectionClosed.IsCancellationRequested)
|
while (!connection.ConnectionClosed.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
var read = await input.ReadAsync(connection.ConnectionClosed).ConfigureAwait(false);
|
var read = await input.ReadAsync(connection.ConnectionClosed).ConfigureAwait(false);
|
||||||
|
|
@ -28,9 +29,19 @@ public class PowerDnsHandler : ConnectionHandler
|
||||||
buffer.Write(memory.Span);
|
buffer.Write(memory.Span);
|
||||||
if (ConsumeJson(buffer, json, ref state))
|
if (ConsumeJson(buffer, json, ref state))
|
||||||
{
|
{
|
||||||
var method = JsonSerializer.Deserialize<Method>(json.WrittenSpan);
|
var method = JsonSerializer.Deserialize(json.WrittenSpan, MethodContext.Default.Method)!;
|
||||||
json.Clear();
|
json.Clear();
|
||||||
state = default;
|
state = default;
|
||||||
|
|
||||||
|
Reply reply = BoolReply.False;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
reply = await Handle(method, connection.ConnectionClosed).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
catch (Exception e) { }
|
||||||
|
|
||||||
|
await JsonSerializer.SerializeAsync(writer, reply, ReplyContext.Default.Reply, connection.ConnectionClosed)
|
||||||
|
.ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -75,4 +86,25 @@ public class PowerDnsHandler : ConnectionHandler
|
||||||
return final;
|
return final;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ValueTask<Reply> Handle(Method method, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
return method switch
|
||||||
|
{
|
||||||
|
InitializeMethod init => HandleInitializeMethod(init),
|
||||||
|
LookupMethod lookup => HandleLookupMethod(lookup),
|
||||||
|
|
||||||
|
_ => ValueTask.FromResult<Reply>(new BoolReply(false))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private ValueTask<Reply> HandleInitializeMethod(InitializeMethod method)
|
||||||
|
{
|
||||||
|
return ValueTask.FromResult(BoolReply.True);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ValueTask<Reply> HandleLookupMethod(LookupMethod method)
|
||||||
|
{
|
||||||
|
return ValueTask.FromResult(BoolReply.False);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,46 @@
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace pdns_dhcp.PowerDns;
|
namespace pdns_dhcp.PowerDns;
|
||||||
|
|
||||||
|
[JsonDerivedType(typeof(BoolReply))]
|
||||||
|
[JsonDerivedType(typeof(LookupReply))]
|
||||||
public abstract class Reply;
|
public abstract class Reply;
|
||||||
|
|
||||||
|
[JsonSerializable(typeof(Reply)), JsonSourceGenerationOptions(
|
||||||
|
GenerationMode = JsonSourceGenerationMode.Serialization,
|
||||||
|
PropertyNamingPolicy = JsonKnownNamingPolicy.KebabCaseLower,
|
||||||
|
WriteIndented = false
|
||||||
|
)]
|
||||||
|
internal partial class ReplyContext : JsonSerializerContext;
|
||||||
|
|
||||||
public abstract class Reply<T>(T result) : Reply
|
public abstract class Reply<T>(T result) : Reply
|
||||||
{
|
{
|
||||||
public T Result => result;
|
public T Result => result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BoolReply(bool result) : Reply<bool>(result);
|
public class BoolReply(bool result) : Reply<bool>(result)
|
||||||
|
{
|
||||||
|
public static Reply False { get; } = new BoolReply(false);
|
||||||
|
|
||||||
|
public static Reply True { get; } = new BoolReply(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LookupReply(QueryResult[] result) : Reply<QueryResult[]>(result);
|
||||||
|
|
||||||
|
public record QueryResult(
|
||||||
|
[property: JsonPropertyName("qtype")] string QType,
|
||||||
|
[property: JsonPropertyName("qname")] string QName,
|
||||||
|
[property: JsonPropertyName("content")] string Content,
|
||||||
|
[property: JsonPropertyName("ttl")] int TTL
|
||||||
|
)
|
||||||
|
{
|
||||||
|
[JsonPropertyName("auth")]
|
||||||
|
public bool? Auth { get; init; } = default;
|
||||||
|
|
||||||
|
[JsonPropertyName("domain_id")]
|
||||||
|
public int? DomainId { get; init; } = default;
|
||||||
|
|
||||||
|
[JsonPropertyName("scopeMask")]
|
||||||
|
public int? ScopeMask { get; init; } = default;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue