예제 #1
0
파일: driver.go 프로젝트: kippandrew/docker
// Allocate an external port and map it to the interface
func AllocatePort(job *engine.Job) engine.Status {
	var (
		err error

		ip            = defaultBindingIP
		id            = job.Args[0]
		hostIP        = job.Getenv("HostIP")
		hostPort      = job.GetenvInt("HostPort")
		containerPort = job.GetenvInt("ContainerPort")
		proto         = job.Getenv("Proto")
		network       = currentInterfaces[id]
	)

	if hostIP != "" {
		ip = net.ParseIP(hostIP)
	}

	// host ip, proto, and host port
	hostPort, err = portallocator.RequestPort(ip, proto, hostPort)
	if err != nil {
		job.Error(err)
		return engine.StatusErr
	}

	var (
		container net.Addr
		host      net.Addr
	)

	if proto == "tcp" {
		host = &net.TCPAddr{IP: ip, Port: hostPort}
		container = &net.TCPAddr{IP: network.IP, Port: containerPort}
	} else {
		host = &net.UDPAddr{IP: ip, Port: hostPort}
		container = &net.UDPAddr{IP: network.IP, Port: containerPort}
	}

	if err := portmapper.Map(container, ip, hostPort); err != nil {
		portallocator.ReleasePort(ip, proto, hostPort)

		job.Error(err)
		return engine.StatusErr
	}
	network.PortMappings = append(network.PortMappings, host)

	out := engine.Env{}
	out.Set("HostIP", ip.String())
	out.SetInt("HostPort", hostPort)

	if _, err := out.WriteTo(job.Stdout); err != nil {
		job.Error(err)
		return engine.StatusErr
	}
	return engine.StatusOK
}
예제 #2
0
파일: network.go 프로젝트: rollbar/docker
// Allocate an external port and map it to the interface
func (iface *NetworkInterface) AllocatePort(port Port, binding PortBinding) (*Nat, error) {

	if iface.disabled {
		return nil, fmt.Errorf("Trying to allocate port for interface %v, which is disabled", iface) // FIXME
	}

	ip := iface.manager.defaultBindingIP

	if binding.HostIp != "" {
		ip = net.ParseIP(binding.HostIp)
	} else {
		binding.HostIp = ip.String()
	}

	nat := &Nat{
		Port:    port,
		Binding: binding,
	}

	containerPort, err := parsePort(port.Port())
	if err != nil {
		return nil, err
	}

	hostPort, _ := parsePort(nat.Binding.HostPort)

	extPort, err := portallocator.RequestPort(ip, nat.Port.Proto(), hostPort)
	if err != nil {
		return nil, err
	}

	var backend net.Addr
	if nat.Port.Proto() == "tcp" {
		backend = &net.TCPAddr{IP: iface.IPNet.IP, Port: containerPort}
	} else {
		backend = &net.UDPAddr{IP: iface.IPNet.IP, Port: containerPort}
	}

	if err := portmapper.Map(backend, ip, extPort); err != nil {
		portallocator.ReleasePort(ip, nat.Port.Proto(), extPort)
		return nil, err
	}

	nat.Binding.HostPort = strconv.Itoa(extPort)
	iface.extPorts = append(iface.extPorts, nat)

	return nat, nil
}