moby: Windows: Wrong source ip in udp packets when port mapping like 8080:8080

In an application running in container, Binding to interface and port used in mapping would cause 0.0.0.0 being set as source ip. Using other ports would not cause this behaviour.

Steps to reproduce the issue:

  1. docker run -it -p 8080:8080/udp microsoft/dotnet:2.1-runtime-nanoserver-1709 cmd or docker run -it -p 8080:8080/udp microsoft/windowsservercore:1709 cmd or any other windows container image!
  2. Run a program that binds to interface with port of 8080 and then sends packets to outside
  3. Use wireshark to capture packets.

Describe the results you received: Using WireShark, packets captured all have “0.0.0.0” as their source ip address.

Describe the results you expected: Source ip should be of the host ip.

Additional information you deem important (e.g. issue happens only occasionally): If you use other ports to send packets, source ip is correct.

Output of docker version:

Client:
 Version:           18.06.0-ce
 API version:       1.38
 Go version:        go1.10.3
 Git commit:        0ffa825
 Built:             Wed Jul 18 19:05:28 2018
 OS/Arch:           windows/amd64
 Experimental:      false

Server:
 Engine:
  Version:          18.06.0-ce
  API version:      1.38 (minimum version 1.24)
  Go version:       go1.10.3
  Git commit:       0ffa825
  Built:            Wed Jul 18 19:23:19 2018
  OS/Arch:          windows/amd64
  Experimental:     true

Output of docker info:

Containers: 62
 Running: 2
 Paused: 0
 Stopped: 60
Images: 3
Server Version: 18.06.0-ce
Storage Driver: windowsfilter (windows) lcow (linux)
 Windows:
 LCOW:
Logging Driver: json-file
Plugins:
 Volume: local
 Network: ics l2bridge l2tunnel nat null overlay transparent
 Log: awslogs etwlogs fluentd gelf json-file logentries splunk syslog
Swarm: inactive
Default Isolation: hyperv
Kernel Version: 10.0 16299 (16299.431.amd64fre.rs3_release_svc_escrow.180502-1908)
Operating System: Windows 10 Enterprise Version 1709 (OS Build 16299.551)
OSType: windows
Architecture: x86_64
CPUs: 8
Total Memory: 31.88GiB
Name: *******
ID: JQUA:NUIA:5MB7:GD32:DGJZ:O6WA:W6WB:ROTF:XRUP:AYOO:ZPAX:GWGE
Docker Root Dir: C:\ProgramData\Docker
Debug Mode (client): false
Debug Mode (server): true
 File Descriptors: -1
 Goroutines: 115
 System Time: 2018-08-23T14:05:00.367736-06:00
 EventsListeners: 2
Registry: https://index.docker.io/v1/
Labels:
Experimental: true
Insecure Registries:
 127.0.0.0/8
Live Restore Enabled: false

Additional environment details (AWS, VirtualBox, physical, etc.): I’ve tested with stable version of docker and edge. All same. I’ve had this issue for past year and half so already tested with previous versions of Windows too. same thing. I’ve tested this with all other versions of Windows containers I could run and also nanoserver. This issue is with using netowrk type of NAT. I dont know of other networking modes, as they dont work for my application. I’ve tested this with several clean installations of Windows two, without any other application installed.

Here is the c++ code you can use for binding :

// ConsoleCPP.cpp : This file contains the 'main' function. Program execution begins and ends there.
//

#include "pch.h"
#include <iostream>

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>


#define DST_PORT    8080
#define SRC_PORT    8080

#define IP      "8.8.8.8" // or any address outside of your network
#define SRCIP   "172.20.218.22" // or use INADDR_ANY


int main()
{
    std::cout << "Hello!\n"; 

	//----------------------
// Initialize Winsock
	int iResult = 0;
	WSADATA wsaData;
	iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (iResult != NO_ERROR) {
		wprintf(L"Error at WSAStartup()\n");
		return 1;
	}

	struct sockaddr_in addr, srcaddr;
	int fd;
	char message[] = "Hello, World!";

	if ((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
		std::cout << "socket error!\n" << fd;
		exit(1);
	}

	std::cout << "socket done!\n";

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = inet_addr(IP);
	addr.sin_port = htons(DST_PORT);

	memset(&srcaddr, 0, sizeof(srcaddr));
	srcaddr.sin_family = AF_INET;
	//srcaddr.sin_addr.s_addr = inet_addr(SRCIP);
	srcaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	srcaddr.sin_port = htons(SRC_PORT);

	if (bind(fd, (struct sockaddr *) &srcaddr, sizeof(srcaddr)) < 0) {
		perror("bind");
		exit(1);
	}

	struct sockaddr_in sockres;
	int sz = sizeof(sockres);
	getsockname(fd, (struct sockaddr *)&sockres, &sz);
	printf("%d %d \n", sockres.sin_addr.S_un.S_un_b.s_b1, sockres.sin_addr.S_un.S_un_b.s_b2);

	std::cout << "bind done!\n";

	while (1) {
		if (sendto(fd, message, sizeof(message), 0, (struct sockaddr *) &addr,
			sizeof(addr)) < 0) {
			perror("sendto");
			exit(1);
		}
		Sleep(1);
	}

	std::cout << "DONE!\n";
}

If you dont bind and then send packet, it will be ok, as some random port will be assigned. Or if you use other port and bind then it will also be ok.

Also to calrify if you run docker run -it -p 8080:8888/udp microsoft/windowsservercore:1709 cmd

Then the issue is binding to port 8080. Still source ip would be “0.0.0.0”

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Comments: 24 (9 by maintainers)

Most upvoted comments

cc @dineshgovindasamy and @jmesser81 from Windows networking team. They should be able to route this [pun intended] to the right person

Status Update: We have a private backport for Windows Server 2019 generated for this issue containing the upstream fix. It’s been validated internally on future Windows release bits+Windows Server 2019 and now we are following up with users affected by this issue for end-user validation. This is needed before it’s possible to backport this officially to Windows Server 2019 for all.

Thanks to additional end-user validation, the ETA for this fix is before the end of June 2019 on Windows Server 2019 (assuming there are no unexpected last-minute show stoppers). Thank you for all your patience in the meanwhile.

@olljanat Sure, the MSFT-internal tracking bug for this issue is 20310680.