Allow public IPv4 addresses for direct SRTP calls
Use shared unicast IPv4 validation for interface discovery, media endpoints and server signaling. Preserve disclosure consent and privacy constraints, and document direct connectivity requirements. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
7f0e868a32
commit
73411f2f7e
8 changed files with 65 additions and 22 deletions
|
|
@ -114,6 +114,18 @@ public sealed class LanCallViewModelTests
|
|||
return vm;
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public async Task Public_ipv4_can_be_selected_for_an_explicitly_consented_direct_call()
|
||||
{
|
||||
var signaling = new Signaling();
|
||||
await using var vm = Configure(signaling, (_, _) => throw new Exception("No media before acceptance"));
|
||||
vm.Addresses.Add("8.8.8.8");
|
||||
vm.Address = "8.8.8.8";
|
||||
await vm.InviteCommand.ExecuteAsync(null);
|
||||
Assert.Equal(1, signaling.Invites);
|
||||
Assert.True(vm.Busy);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public async Task No_capture_starts_before_explicit_acceptance_and_endpoint_exchange()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ public sealed class LibVlcLanCallMedia : IAsyncDisposable
|
|||
Endpoint = new(localAddress, port, Convert.ToHexString(RandomNumberGenerator.GetBytes(16)),
|
||||
Convert.ToHexString(RandomNumberGenerator.GetBytes(14)));
|
||||
if (!Endpoint.IsValid())
|
||||
throw new ArgumentException("Adresse IPv4 privee et port UDP pair (1024-65534) requis.");
|
||||
throw new ArgumentException("Adresse IPv4 unicast et port UDP pair (1024-65534) requis.");
|
||||
using (var reservation = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
|
||||
using (var rtcp = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ public partial class LanCallViewModel : ObservableObject, IAsyncDisposable
|
|||
foreach (var address in NetworkInterface.GetAllNetworkInterfaces()
|
||||
.Where(n => n.OperationalStatus == OperationalStatus.Up)
|
||||
.SelectMany(n => n.GetIPProperties().UnicastAddresses)
|
||||
.Select(a => a.Address.ToString()).Where(LanCallNetwork.IsPrivateIPv4)
|
||||
.Select(a => a.Address.ToString()).Where(LanCallNetwork.IsUnicastIPv4)
|
||||
.Distinct().OrderBy(a => IPAddress.IsLoopback(IPAddress.Parse(a))))
|
||||
Addresses.Add(address);
|
||||
Address = preferred == null ? Addresses.FirstOrDefault() : Addresses.FirstOrDefault(a => a == preferred);
|
||||
|
|
@ -181,7 +181,7 @@ public partial class LanCallViewModel : ObservableObject, IAsyncDisposable
|
|||
Status = Cameras.Count == 0 ? "Aucune camera detectee. Verifiez les peripheriques puis actualisez."
|
||||
: Incoming && _call != null
|
||||
? $"{_call.Caller} propose un appel dans {_call.RoomName}. Selectionnez vos peripheriques puis acceptez ou refusez."
|
||||
: "Selectionnez le pair, l'adresse LAN/VPN et les peripheriques. Utilisez un casque.";
|
||||
: "Selectionnez le pair, l'adresse IPv4 locale ou publique et les peripheriques. Utilisez un casque.";
|
||||
if (_settings != null)
|
||||
{
|
||||
_settings.PodcastCameras = Cameras.ToArray();
|
||||
|
|
@ -200,10 +200,10 @@ public partial class LanCallViewModel : ObservableObject, IAsyncDisposable
|
|||
private void ValidateSelection()
|
||||
{
|
||||
if (!AllowAddressDisclosure)
|
||||
throw new InvalidOperationException("Confirmez le partage de votre adresse LAN/VPN avec le pair.");
|
||||
throw new InvalidOperationException("Confirmez le partage de votre adresse IPv4 avec le pair.");
|
||||
if (Camera == null || Microphone == null)
|
||||
throw new InvalidOperationException("Une camera et un microphone sont requis.");
|
||||
if (Address == null || !Addresses.Contains(Address) || !LanCallNetwork.IsPrivateIPv4(Address) ||
|
||||
if (Address == null || !Addresses.Contains(Address) || !LanCallNetwork.IsUnicastIPv4(Address) ||
|
||||
!int.TryParse(Port, out var port) || port is < 1024 or > 65534 || port % 2 != 0)
|
||||
throw new InvalidOperationException("Selectionnez une adresse locale et un port UDP pair (1024-65534).");
|
||||
_activeCamera = Camera.Value;
|
||||
|
|
|
|||
|
|
@ -103,16 +103,16 @@
|
|||
Content="Envoyer" />
|
||||
</Grid>
|
||||
|
||||
<Expander Grid.Row="3" Header="Appel direct (LAN/VPN)" IsVisible="{Binding SupportsLanCalls}" IsExpanded="True"
|
||||
<Expander Grid.Row="3" Header="Appel direct IPv4 (LAN/VPN ou IP publique)" IsVisible="{Binding SupportsLanCalls}" IsExpanded="True"
|
||||
IsEnabled="{Binding IsConnected}" Margin="0,0,0,8">
|
||||
<ScrollViewer MaxHeight="520">
|
||||
<StackPanel DataContext="{Binding LanCall}" x:DataType="vm:LanCallViewModel" Spacing="8">
|
||||
<TextBlock Text="Android et Desktop Linux sur LAN/VPN. SRTP chiffre les medias ; le pair connait votre IP. Ouvrir le port UDP choisi et le suivant. Sans TURN ni traversee NAT. Casque recommande (pas d'annulation d'echo)."
|
||||
<TextBlock Text="Android et Desktop Linux : IPv4 locale LAN/VPN ou publique directement assignee au PC. SRTP chiffre les medias ; le pair connait votre IP. Ouvrir le port UDP choisi et le suivant. Sans TURN ni traversee NAT. Casque recommande (pas d'annulation d'echo)."
|
||||
TextWrapping="Wrap" />
|
||||
<WrapPanel IsEnabled="{Binding CanConfigure}" IsVisible="{Binding !RemoteVideo}">
|
||||
<Button Content="Actualiser les peripheriques" Command="{Binding RefreshDevicesCommand}" Margin="0,0,8,4" />
|
||||
<ComboBox Width="160" ItemsSource="{Binding Addresses}" SelectedItem="{Binding Address}"
|
||||
PlaceholderText="Adresse locale LAN/VPN" Margin="0,0,8,4" />
|
||||
PlaceholderText="Adresse IPv4 de cette machine" Margin="0,0,8,4" />
|
||||
<TextBox Width="80" Text="{Binding Port}" PlaceholderText="Port pair" Margin="0,0,8,4" />
|
||||
<ComboBox Width="190" ItemsSource="{Binding Cameras}" SelectedItem="{Binding Camera}"
|
||||
PlaceholderText="Camera" Margin="0,0,8,4">
|
||||
|
|
@ -132,7 +132,7 @@
|
|||
</ComboBox>
|
||||
<TextBox Width="170" Text="{Binding Target}" PlaceholderText="Pseudo du pair" Margin="0,0,8,4" />
|
||||
</WrapPanel>
|
||||
<CheckBox Content="Je consens a partager mon adresse LAN/VPN avec le pair."
|
||||
<CheckBox Content="Je consens a partager mon adresse IPv4 avec le pair."
|
||||
IsChecked="{Binding AllowAddressDisclosure}" IsEnabled="{Binding CanConfigure}"
|
||||
IsVisible="{Binding !RemoteVideo}" />
|
||||
<WrapPanel>
|
||||
|
|
|
|||
Loading…
Reference in a new issue