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;
|
||||
|
||||
namespace pdns_dhcp.PowerDns;
|
||||
|
|
@ -8,19 +7,21 @@ public interface IMethod;
|
|||
[JsonPolymorphic(TypeDiscriminatorPropertyName = "method")]
|
||||
[JsonDerivedType(typeof(InitializeMethod), "initialize")]
|
||||
[JsonDerivedType(typeof(LookupMethod), "lookup")]
|
||||
public abstract class Method
|
||||
{
|
||||
[JsonExtensionData]
|
||||
public Dictionary<string, JsonElement> ExtensionData { get; } = [];
|
||||
}
|
||||
public class Method;
|
||||
|
||||
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 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;
|
||||
using ArrayPoolBufferWriter<byte> json = new();
|
||||
using ArrayPoolBufferWriter<byte> buffer = new();
|
||||
using var writer = connection.Transport.Output.AsStream();
|
||||
while (!connection.ConnectionClosed.IsCancellationRequested)
|
||||
{
|
||||
var read = await input.ReadAsync(connection.ConnectionClosed).ConfigureAwait(false);
|
||||
|
|
@ -28,9 +29,19 @@ public class PowerDnsHandler : ConnectionHandler
|
|||
buffer.Write(memory.Span);
|
||||
if (ConsumeJson(buffer, json, ref state))
|
||||
{
|
||||
var method = JsonSerializer.Deserialize<Method>(json.WrittenSpan);
|
||||
var method = JsonSerializer.Deserialize(json.WrittenSpan, MethodContext.Default.Method)!;
|
||||
json.Clear();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
[JsonDerivedType(typeof(BoolReply))]
|
||||
[JsonDerivedType(typeof(LookupReply))]
|
||||
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 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