Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,15 @@ A simple, zero-config DLNA media server, that you can just fire up and be done w


See [the github page](http://nmaier.github.io/simpleDLNA/) for more details and downloads.


What's new
----------

- Added `--uuid` command-line option to set a static server UUID, e.g.:

```
sdlna.exe --uuid 12345678-1234-1234-1234-123456789abc D:\Media
```

- Device UUIDs are now derived deterministically from the server UUID and the IP address. This keeps device identifiers stable across restarts as long as the server UUID and IP remain the same.
13 changes: 11 additions & 2 deletions fsserver/FileServer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -57,6 +57,8 @@ public sealed class FileServer

private FileStore store;

private Guid uuid;

public FileServer(DlnaMediaTypes types, Identifiers ids,
params DirectoryInfo[] directories)
{
Expand All @@ -80,6 +82,13 @@ public FileServer(DlnaMediaTypes types, Identifiers ids,
UUID = DeriveUUID();
}

public FileServer(DlnaMediaTypes types, Identifiers ids, Guid fixedUuid,
params DirectoryInfo[] directories)
: this(types, ids, directories)
{
UUID = fixedUuid;
}

internal ExtensionFilter Filter { get; }

public void Dispose()
Expand All @@ -98,7 +107,7 @@ public void Dispose()
public string FriendlyName { get; set; }

// ReSharper disable once MemberInitializerValueIgnored
public Guid UUID { get; } = Guid.NewGuid();
public Guid UUID { get; private set; } = Guid.NewGuid();

public IMediaItem GetItem(string id)
{
Expand Down
24 changes: 24 additions & 0 deletions sdlna/Options.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,30 @@ internal class Options : GetOpt

[Argument("view", HelpText = "Apply a view (default: no views applied)", HelpVar = "view")] [ShortArgument('v')] public string[] Views = new string[0];

private Guid? uuid;

[Argument("uuid", HelpText = "Static server UUID (e.g. 12345678-1234-1234-1234-123456789abc)", HelpVar = "uuid")]
public string Uuid
{
get { return uuid?.ToString(); }
set {
if (string.IsNullOrWhiteSpace(value)) {
uuid = null;
return;
}
Guid parsed;
if (!Guid.TryParse(value, out parsed)) {
throw new GetOptException($"Not a valid UUID: {value}");
}
uuid = parsed;
}
}

public Guid? ParsedUuid
{
get { return uuid; }
}

[Argument("ip", HelpText = "Allow only specified IPs", HelpVar = "IP")]
[ShortArgument('i')]
public string[] Ips
Expand Down
8 changes: 7 additions & 1 deletion sdlna/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,13 @@ private static FileServer SetupFileServer(Options options,
throw new GetOptException("Invalid view " + v);
}
}
var fs = new FileServer(types, ids, d);
FileServer fs;
if (options.ParsedUuid.HasValue) {
fs = new FileServer(types, ids, options.ParsedUuid.Value, d);
}
else {
fs = new FileServer(types, ids, d);
}
try {
if (!string.IsNullOrEmpty(options.FriendlyName)) {
fs.FriendlyName = options.FriendlyName;
Expand Down
19 changes: 18 additions & 1 deletion server/Http/HTTPServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ public void RegisterMediaServer(IMediaServer server)

foreach (var address in IP.ExternalIPAddresses) {
DebugFormat("Registering device for {0}", address);
var deviceGuid = Guid.NewGuid();
var deviceGuid = DeriveDeviceUuid(guid, address);
var list = devicesForServers.GetOrAdd(guid, new List<Guid>());
lock (list) {
list.Add(deviceGuid);
Expand All @@ -271,6 +271,23 @@ public void RegisterMediaServer(IMediaServer server)
}
}

private static Guid DeriveDeviceUuid(Guid serverUuid, IPAddress address)
{
// Стабильный UUID на основе UUID сервера и адреса устройства (per-IP)
var serverBytes = serverUuid.ToByteArray();
var addrBytes = address.GetAddressBytes();
var combined = new byte[16];
for (var i = 0; i < 16; i++) {
var sb = serverBytes[i];
var ab = addrBytes[i % addrBytes.Length];
combined[i] = (byte)(sb ^ ab);
}
// Установка версии 4 и варианта RFC 4122 для корректной формы UUID
combined[6] = (byte)((combined[6] & 0x0F) | 0x40);
combined[8] = (byte)((combined[8] & 0x3F) | 0x80);
return new Guid(combined);
}

public void UnregisterMediaServer(IMediaServer server)
{
if (server == null) {
Expand Down