Repository: mageddo/dns-proxy-server (java)

Issue:
Windows Binary: Docker containers Solving 
> Docker container solving is already supported on Windows when running on docker container, see [the docs][1]

### What is expected

Be able to solve containers by configured hostnames 

### What is happening

DPS is not able to connect to docker and retrieve the containers data.

### Changes (Optional)

=> Need to think how DPS will connect to docker running on wsl1 or wls2

https://learn.microsoft.com/en-us/windows/wsl/tutorials/wsl-containers

```
C:\Users\Typer>docker context ls
NAME                TYPE                DESCRIPTION                               DOCKER ENDPOINT                             KUBERNETES ENDPOINT   ORCHESTRATOR
default *           moby                Current DOCKER_HOST based configuration   npipe:////./pipe/docker_engine                                    swarm
desktop-linux       moby                                                          npipe:////./pipe/dockerDesktopLinuxEngine

```

[1]: http://mageddo.github.io/dns-proxy-server/3.14/en/1-getting-started/running-it/windows/

Pull request description:
Windows Binary: Docker containers Solving
Fixes #314 

Patch:
diff --git a/.gitattributes b/.gitattributes
index 0b62924b..2181a8f7 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -22,6 +22,9 @@ Dockerfile text eol=lf
 *.Dockerfile text eol=lf
 Dockerfile.* text eol=lf
 *.json text eol=lf
+*.conf text eol=lf
+*.yml text eol=lf
+*.sh text eol=lf
 *.bat text eol=crlf
 
 *.so binary
diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
index df6c634d..049d24ea 100644
--- a/RELEASE-NOTES.md
+++ b/RELEASE-NOTES.md
@@ -1,7 +1,9 @@
-## 3.14.2-snapshot
+## 3.14.3-snapshot
 * Support for regex on localdb solver and docker container hostname and HOSTNAMES env
 * Smarter Cache for loading with Docker and LocalDB Solvers see #376
 * Docker host parameter by flag, json config or env
+* Full support for Docker containers solving on Windows Binary, DPS on docker already works on Windows
+* Prefer to solve real network card address when querying for `host.docker`
 
 ## 3.13.1
 * Caching remote solved hostnames for 5 minutes
diff --git a/docs/content/1-getting-started/running-it/mac/_index.en.md b/docs/content/1-getting-started/running-it/mac/_index.en.md
index 4634934a..44551386 100644
--- a/docs/content/1-getting-started/running-it/mac/_index.en.md
+++ b/docs/content/1-getting-started/running-it/mac/_index.en.md
@@ -4,7 +4,8 @@ weight: 1
 ---
 ## Running on MAC
 
-DPS actually is fully supported on MAC knowing [docker limitation features][5].
+DPS actually is fully supported on MAC knowing [docker limitation features][5]
+which can be bypassed with a [reverse-proxy][10].
 
 ## Running as Docker as service
 
@@ -73,3 +74,4 @@ See [this thread][6] with more use cases.
 [5]: https://docs.docker.com/desktop/networking/#there-is-no-docker0-bridge-on-the-host
 [6]: https://github.com/mageddo/dns-proxy-server/issues/44#issuecomment-1454379761
 [7]: #configuring-dps-as-default-dns-manually
+[10]: {{%relref "5-tutorials/docker-reverse-proxy/_index.md" %}}
diff --git a/docs/content/1-getting-started/running-it/windows/_index.en.md b/docs/content/1-getting-started/running-it/windows/_index.en.md
index a48ee657..d1da9a2a 100644
--- a/docs/content/1-getting-started/running-it/windows/_index.en.md
+++ b/docs/content/1-getting-started/running-it/windows/_index.en.md
@@ -4,15 +4,15 @@ weight: 1
 ---
 
 ## Running on Windows
-You can run DPS on Windows host without any issues except by DPS isn't capable yet
-to connect to docker API and solve containers ([see backlog issue][4]).
+DPS actually is fully supported on Windows knowing [docker limitation features][9] 
+which can be bypassed with a [reverse-proxy][10].
 
 ## Running as Docker Service
 
 1- If you are using docker on your machine that's the best choice as it will automatically start DPS on every boot:
 
 ```bash
-$ docker run -d --restart=unless-stopped -p 53:53/udp -p 53:53/tcp -p 5380:5380 defreitas/dns-proxy-server
+$ docker run -d --restart=unless-stopped -p 53:53/udp -p 53:53/tcp -p 5380:5380 -v /var/run/docker.sock:/var/run/docker.sock defreitas/dns-proxy-server
 ```
 
 2- Set DPS as the default DNS on Windows, check the instructions below on 
@@ -45,7 +45,7 @@ You can access the GUI by the address http://localhost:5380/ , see [GUI Dashboar
 * Download the [latest release][5] for Windows
 * Run dps by `dns-proxy-server.exe`
 
-If you run DPS as administrator (using administrator prompt) then it will capable of configure itself as the [default DNS][6]
+If you run DPS as administrator then it will capable of configure itself as the [default DNS][6]
 or check instructions below of how to set DPS as default DNS manually.
 
 ## Configure DPS as default DNS on Windows
@@ -86,8 +86,9 @@ then requests won't be sent to DPS, actually DPS doesn't support IPV6.
 ![Screenshot](https://i.imgur.com/0bxASqd.png?width=10pc&classes=shadow)
 
 [1]: https://imgur.com/a/LlDH8AM
-[4]: https://github.com/mageddo/dns-proxy-server/issues/314
 [5]: https://github.com/mageddo/dns-proxy-server/releases
 [6]: {{%relref "2-features/auto-configuration-as-default-dns/_index.md" %}}
 [7]: #configure-dps-as-default-dns-on-windows
 [8]: {{%relref "2-features/gui/_index.md" %}}
+[9]: https://docs.docker.com/desktop/networking/#there-is-no-docker0-bridge-on-the-host
+[10]: {{%relref "5-tutorials/docker-reverse-proxy/_index.md" %}}
diff --git a/docs/content/5-tutorials/docker-reverse-proxy.en.md b/docs/content/5-tutorials/docker-reverse-proxy.en.md
index 1e639735..8af91802 100644
--- a/docs/content/5-tutorials/docker-reverse-proxy.en.md
+++ b/docs/content/5-tutorials/docker-reverse-proxy.en.md
@@ -9,7 +9,7 @@ menuTitle: Create a Service Discovery solution
 ##### Tested on: 
 
 * DPS 3.11
-* OS: Mac, Linux
+* OS: Mac, Linux, Windows
 
 #### Introducing
 
@@ -26,9 +26,6 @@ accessible from the host.
 To fix that we will configure an API Gateway, Service Discovery, Reverse Proxy solution combining DPS with Nginx,
 see final solution below:
 
-> Obs: This tutorial won't work on Windows yet because containers solving is not support yet,
-> follow the [feature request issue][1] on github.
-
 ![][2]
 Source: [excalidraw][3]
 
@@ -38,8 +35,9 @@ The pratice is simpler than the theory, let's get it working:
 Configuring Nginx reverse proxy and two web apps for test
 ```bash
 $ git clone https://github.com/mageddo/dns-proxy-server.git
-$ cd examples/api-gateway_service-discovery_reverse-proxyame-compose-file
-$ docker-compose up --build
+$ cd examples/api-gateway_service-discovery_reverse-proxy
+$ docker-compose build --no-cache
+$ docker-compose up
 ```
 
 `docker-compose up` created three containers, the first is a nginx reverse proxy which will listen to the host machine
@@ -113,7 +111,6 @@ thanks for reading.
 
 > Service Discovery, API Gateway, Service Discovery, Reverse Proxy
 
-[1]: https://github.com/mageddo/dns-proxy-server/issues/314
 [2]: https://i.imgur.com/poI0sKZ.png
 [3]: https://excalidraw.com/#json=BuYYx179GhmvHCexDZHGv,2hN_IgZo9HTfID-neSACQw
 [4]: {{%relref "1-getting-started/running-it/_index.md" %}}
diff --git a/examples/api-gateway_service-discovery_reverse-proxy/Dockerfile b/examples/api-gateway_service-discovery_reverse-proxy/Dockerfile
index b50b050c..7f8e565f 100644
--- a/examples/api-gateway_service-discovery_reverse-proxy/Dockerfile
+++ b/examples/api-gateway_service-discovery_reverse-proxy/Dockerfile
@@ -2,4 +2,4 @@ FROM nginx:1.23
 COPY nginx/reverse-proxy.conf /etc/nginx/conf.d/default.conf
 COPY nginx/nginx.conf /etc/nginx/nginx.conf
 COPY nginx/entrypoint.sh /app/entrypoint.sh
-ENTRYPOINT /app/entrypoint.sh
+ENTRYPOINT ["/app/entrypoint.sh"]
diff --git a/examples/api-gateway_service-discovery_reverse-proxy/nginx/entrypoint.sh b/examples/api-gateway_service-discovery_reverse-proxy/nginx/entrypoint.sh
index c139085a..a2da2530 100755
--- a/examples/api-gateway_service-discovery_reverse-proxy/nginx/entrypoint.sh
+++ b/examples/api-gateway_service-discovery_reverse-proxy/nginx/entrypoint.sh
@@ -12,3 +12,4 @@ echo "> configured: $(cat $CONFIG_FILE)"
 echo "> starting nginx server"
 
 exec nginx -g 'daemon off;'
+
diff --git a/gradle.properties b/gradle.properties
index 044be663..2cb21278 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,1 +1,1 @@
-version=3.14.2-snapshot
+version=3.14.3-snapshot
diff --git a/src/main/java/com/mageddo/dnsproxyserver/docker/DockerConnectionCheck.java b/src/main/java/com/mageddo/dnsproxyserver/docker/DockerConnectionCheck.java
index 29bbfc0a..a9a096da 100644
--- a/src/main/java/com/mageddo/dnsproxyserver/docker/DockerConnectionCheck.java
+++ b/src/main/java/com/mageddo/dnsproxyserver/docker/DockerConnectionCheck.java
@@ -39,7 +39,7 @@ public class DockerConnectionCheck {
   }
 
   boolean isSupportedPlatform() {
-    return Platform.isLinux() || Platform.isMac();
+    return Platform.isLinux() || Platform.isMac() || Platform.isWindows();
   }
 
   void updateStatus() {
diff --git a/src/main/java/com/mageddo/dnsproxyserver/server/dns/IP.java b/src/main/java/com/mageddo/dnsproxyserver/server/dns/IP.java
index dbbefedb..df0636b7 100644
--- a/src/main/java/com/mageddo/dnsproxyserver/server/dns/IP.java
+++ b/src/main/java/com/mageddo/dnsproxyserver/server/dns/IP.java
@@ -64,4 +64,8 @@ public class IP {
     }
     return IP.of(ip).toShortArray();
   }
+
+  public boolean isLoopback() {
+    return this.ip.startsWith("127.");
+  }
 }
diff --git a/src/main/java/com/mageddo/dnsproxyserver/server/dns/solver/SolverSystem.java b/src/main/java/com/mageddo/dnsproxyserver/server/dns/solver/SolverSystem.java
index f95e74f4..6b5e86a1 100644
--- a/src/main/java/com/mageddo/dnsproxyserver/server/dns/solver/SolverSystem.java
+++ b/src/main/java/com/mageddo/dnsproxyserver/server/dns/solver/SolverSystem.java
@@ -1,8 +1,8 @@
 package com.mageddo.dnsproxyserver.server.dns.solver;
 
 import com.mageddo.dnsproxyserver.config.Configs;
-import com.mageddo.dnsproxyserver.docker.DockerDAO;
 import com.mageddo.dnsproxyserver.server.dns.Messages;
+import com.mageddo.dnsproxyserver.usecase.HostMachineService;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.xbill.DNS.Message;
@@ -15,14 +15,14 @@ import javax.inject.Singleton;
 @AllArgsConstructor(onConstructor = @__({@Inject}))
 public class SolverSystem implements Solver {
 
-  private final DockerDAO dockerDAO;
+  private final HostMachineService machineService;
 
   @Override
   public Response handle(Message query) {
     final var hostname = Messages.findQuestionHostname(query);
     final var config = Configs.getInstance();
     if (hostname.isEqualTo(config.getHostMachineHostname())) { // fixme fazer case com hostname + search domain
-      final var ip = this.dockerDAO.findHostMachineIp();
+      final var ip = this.machineService.findHostMachineIP();
       if (ip == null) {
         log.debug("status=hostMachineIpNotFound, host={}", hostname);
         return null;
diff --git a/src/main/java/com/mageddo/dnsproxyserver/usecase/HostMachineService.java b/src/main/java/com/mageddo/dnsproxyserver/usecase/HostMachineService.java
new file mode 100644
index 00000000..24afde75
--- /dev/null
+++ b/src/main/java/com/mageddo/dnsproxyserver/usecase/HostMachineService.java
@@ -0,0 +1,32 @@
+package com.mageddo.dnsproxyserver.usecase;
+
+import com.mageddo.dnsproxyserver.docker.DockerDAO;
+import com.mageddo.dnsproxyserver.server.dns.IP;
+import com.mageddo.net.Networks;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import java.util.Optional;
+
+@Singleton
+public class HostMachineService {
+
+  private final DockerDAO dockerDAO;
+
+  @Inject
+  public HostMachineService(DockerDAO dockerDAO) {
+    this.dockerDAO = dockerDAO;
+  }
+
+  public IP findHostMachineIP() {
+    return Optional
+      .ofNullable(Networks.findCurrentMachineIP())
+      .filter(it -> !it.isLoopback())
+      .orElseGet(() -> {
+        if (this.dockerDAO.isConnected()) {
+          return this.dockerDAO.findHostMachineIp();
+        }
+        return null;
+      });
+  }
+}


Test patch:
diff --git a/src/test/java/com/mageddo/dnsproxyserver/config/flags/ConfigFlagTest.java b/src/test/java/com/mageddo/dnsproxyserver/config/flags/ConfigFlagTest.java
index edd69e33..a9e57cda 100644
--- a/src/test/java/com/mageddo/dnsproxyserver/config/flags/ConfigFlagTest.java
+++ b/src/test/java/com/mageddo/dnsproxyserver/config/flags/ConfigFlagTest.java
@@ -45,7 +45,7 @@ class ConfigFlagTest {
     // assert
     assertEquals(
         readString("/flags-test/002.txt"),
-        sw.toString()
+        sw.toString().replaceAll("\r\n", "\n")
     );
     assertTrue(config.getHelp());
   }
@@ -66,3 +66,4 @@ class ConfigFlagTest {
     assertTrue(config.isVersion());
   }
 }
+
diff --git a/src/test/java/com/mageddo/dnsproxyserver/server/dns/solver/SolverSystemCompTest.java b/src/test/java/com/mageddo/dnsproxyserver/server/dns/solver/SolverSystemCompTest.java
index 64818f85..6162c24b 100644
--- a/src/test/java/com/mageddo/dnsproxyserver/server/dns/solver/SolverSystemCompTest.java
+++ b/src/test/java/com/mageddo/dnsproxyserver/server/dns/solver/SolverSystemCompTest.java
@@ -1,9 +1,9 @@
 package com.mageddo.dnsproxyserver.server.dns.solver;
 
-import com.mageddo.dnsproxyserver.docker.DockerDAO;
 import com.mageddo.dnsproxyserver.server.dns.IP;
 import com.mageddo.dnsproxyserver.server.dns.Messages;
 import com.mageddo.dnsproxyserver.templates.MessageTemplates;
+import com.mageddo.dnsproxyserver.usecase.HostMachineService;
 import dagger.sheath.InjectMock;
 import dagger.sheath.junit.DaggerTest;
 import org.hamcrest.CoreMatchers;
@@ -22,7 +22,7 @@ import static org.mockito.Mockito.verify;
 class SolverSystemCompTest {
 
   @InjectMock
-  DockerDAO dockerDAO;
+  HostMachineService machineService;
 
   @Inject
   SolverSystem solver;
@@ -34,8 +34,8 @@ class SolverSystemCompTest {
     final var query = MessageTemplates.buildAQuestionFor(hostname);
 
     doReturn(IP.of("192.168.0.1"))
-      .when(this.dockerDAO)
-      .findHostMachineIp()
+      .when(this.machineService)
+      .findHostMachineIP()
     ;
 
     // act
@@ -46,7 +46,7 @@ class SolverSystemCompTest {
     assertThat(answer, CoreMatchers.containsString(hostname));
     assertEquals("host.docker.\t\t30\tIN\tA\t192.168.0.1", answer);
 
-    verify(this.dockerDAO).findHostMachineIp();
+    verify(this.machineService).findHostMachineIP();
   }
 
 }