Exemple #1
0
func (s *Server) Handle(conn net.Conn) {
	defer conn.Close()
	ccfb := cipher.NewCFBDecrypter(s.ClientCipher, iv)
	scfb := cipher.NewCFBEncrypter(s.ServerCipher, iv)
	out := make([]byte, 1024)
	readAndDecode(conn, out[:4], ccfb)
	if out[1] != 1 {
		log.Print("unsupport command")
		return
	}
	addr := new(net.TCPAddr)
	switch out[3] { //atyp
	case 1: //ipv4
		readAndDecode(conn, out[:4], ccfb)
		addr.IP = net.IPv4(out[0], out[1], out[2], out[3])
	case 3: //domain
		readAndDecode(conn, out[:1], ccfb)
		l := out[0]
		readAndDecode(conn, out[:l], ccfb)
		host := string(out[:l])
		addrs, err := net.LookupIP(host)
		if err != nil || len(addrs) == 0 {
			log.Print("cannot resolve ", host)
			return
		}
		addr.IP = addrs[0]
	default:
		log.Print("unsupport address type")
		return
	}
	readAndDecode(conn, out[:2], ccfb)
	addr.Port = nl2int(out)

	sConn, err := net.DialTCP("tcp", nil, addr)
	if err != nil {
		log.Print("cannot connect to server", addr.String())
		encodeAndWrite(conn, out[:10], scfb)
		return
	}
	defer sConn.Close()
	response := make([]byte, 10)
	response[0] = 5
	response[1] = 0
	response[2] = 0
	response[3] = 1
	copy(response[4:], sConn.LocalAddr().(*net.TCPAddr).IP)
	copy(response[8:], int2nl(sConn.LocalAddr().(*net.TCPAddr).Port))
	encodeAndWrite(conn, response, scfb)
	go HandleStream(conn, sConn, scfb)
	HandleStream(sConn, conn, ccfb)
}
Exemple #2
0
func MakeConn(ip string) (*net.TCPConn, error) {
	var addr net.TCPAddr
	addr.IP = net.ParseIP(ip)
	addr.Port = Port
	c, err := net.DialTCP("tcp4", nil, &addr)
	return c, err
}
Exemple #3
0
func ts6_main(msg chan string, exit chan int) {

	// No configuration, so this is fixed.
	var addr net.TCPAddr
	addr.IP = net.IPv4(127, 0, 0, 1)
	addr.Port = 3725

	// Start our listener.
	l, err := net.ListenTCP("tcp4", &addr)
	if err != nil {
		fmt.Printf("No bind: %s\n", err)
		exit <- 0
	} else {
		go listen(l)

		// Again, no configuration.
		addr.Port = 13725
		c, err := net.DialTCP("tcp4", nil, &addr)
		if err != nil {
			fmt.Printf("No connection: %s\n", err)
		} else {
			go link(c, true)
		}
	}

	// Handle messages.
	for message := range msg {
		if message == "exit" {
			exit <- 0
		}
	}
}
Exemple #4
0
func main() {
	if len(os.Args) != 2 {
		fmt.Fprintf(os.Stderr, "Usage: %s message", os.Args[0])
		os.Exit(1)
	}
	message := os.Args[1]

	serverIP := "127.0.0.1" //サーバ側のIP
	serverPort := "55555"   //サーバ側のポート番号
	myIP := "127.0.0.1"     //クライアント側のIP
	myPort := 55556         //クライアント側のポート番号

	tcpAddr, err := net.ResolveTCPAddr("tcp", serverIP+":"+serverPort)
	checkError(err)
	myAddr := new(net.TCPAddr)
	myAddr.IP = net.ParseIP(myIP)
	myAddr.Port = myPort
	conn, err := net.DialTCP("tcp", myAddr, tcpAddr)
	checkError(err)
	defer conn.Close()

	conn.SetWriteDeadline(time.Now().Add(10 * time.Second))
	conn.Write([]byte(message))

	readBuf := make([]byte, 1024)
	conn.SetReadDeadline(time.Now().Add(10 * time.Second))
	readlen, err := conn.Read(readBuf)
	checkError(err)

	fmt.Println("server: " + string(readBuf[:readlen]))
}
Exemple #5
0
func TCPAddr(buf []byte) (net.TCPAddr, int) {

	var value net.TCPAddr
	value.IP = make([]byte, 16)
	copy(value.IP, buf[:16])
	value.Port = int(binary.BigEndian.Uint16(buf[16:18]))

	return value, Size

}
Exemple #6
0
func main() {

	var localaddr net.TCPAddr
	var remoteaddr net.TCPAddr
	localaddr.IP = net.ParseIP("192.168.0.109")
	localaddr.Port = 0
	remoteaddr.IP = net.ParseIP("192.168.0.1")
	remoteaddr.Port = 80

	if localaddr.IP == nil || remoteaddr.IP == nil {
		fmt.Println("error")
	}

	if _, err := net.DialTCP("tcp", &localaddr, &remoteaddr); err != nil {
		fmt.Println(err)
	}

	fmt.Println("End")

}
Exemple #7
0
func (bot *Bot) Connect() (conn net.Conn, err error) {
	r, err := net.ResolveTCPAddr("tcp", bot.server+":"+bot.port)
	var l net.TCPAddr
	l.IP = net.ParseIP(bot.local_ip)

	conn, err = net.DialTCP("tcp", nil, r)
	if err != nil {
		log.Fatal("unable to connect to IRC server ", err)
	}
	bot.conn = conn
	log.Printf("Connected to IRC server %s (%s)\n", bot.server, bot.conn.RemoteAddr())
	return bot.conn, nil
}
Exemple #8
0
func (this *MsgBusServer) Dail() error {
	glog.Infof("Dail to [%s]->[%s]\n", this.localAddr, this.remoteAddr)
	var (
		err           error
		tcpLocalAddr  net.TCPAddr
		tcpRemoteAddr *net.TCPAddr
	)

	ip, err := net.ResolveIPAddr("ip", this.localAddr)
	if err != nil || ip.IP == nil {
		glog.Fatalf("Resovle Local TcpAddr [%s], error: %v\n", this.localAddr, err)
	}
	tcpLocalAddr.IP = ip.IP
	//tcpLocalAddr, err = net.ResolveTCPAddr("tcp", this.localAddr)
	//if err != nil {
	//	glog.Errorf("Resovle Local TcpAddr [%s] [%s]\n", this.localAddr, err.Error())
	//	return err
	//}

	tcpRemoteAddr, err = net.ResolveTCPAddr("tcp", this.remoteAddr)
	if err != nil {
		glog.Errorf("Resovle Remote TcpAddr [%s] [%s]\n", this.remoteAddr, err.Error())
		return err
	}
	this.conn, err = net.DialTCP("tcp", &tcpLocalAddr, tcpRemoteAddr)
	if err != nil {
		glog.Errorf("Dail [%s]->[%s] [%s]\n", this.localAddr, this.remoteAddr, err.Error())
		return err
	}
	buf := make([]byte, 1)
	buf[0] = byte(gCometType)
	_, err = this.conn.Write(buf)
	if err != nil {
		glog.Errorf("Send info error [%s]->[%s] [%s]\n", this.localAddr, this.remoteAddr, err.Error())
		return err
	}
	n, err := this.conn.Read(buf)
	if err != nil || n != 1 {
		glog.Errorf("Read ack error [%s]<-[%s] [%s]\n", this.localAddr, this.remoteAddr, err.Error())
		return err
	}

	// glog.Infof("Dail to [%s] ok\n", this.addr)
	return nil
}
Exemple #9
0
// Connect to slimproto
func slimprotoConnect(addr net.IP, port int) {

	sbsAddr := new(net.TCPAddr)
	sbsAddr.IP = addr
	sbsAddr.Port = port

	var err error
	slimproto.Conn, err = net.DialTCP("tcp", nil, sbsAddr)
	checkError(err)
	//slimproto.Conn.SetDeadline(time.Time(10e9))

	if *debug {
		log.Println("Connected to slimproto")
	}

	return

}
Exemple #10
0
func (l *Listener) startListening(config *core.GeneralConfig) (*net.TCPListener, error) {
	var addr net.TCPAddr

	addr.IP = net.ParseIP(config.AdminBind)

	if addr.IP == nil {
		return nil, fmt.Errorf("The admin bind address specified is not a valid IP address")
	}

	addr.Port = config.AdminPort

	listener, err := net.ListenTCP("tcp", &addr)
	if err != nil {
		return nil, err
	}

	return listener, nil
}
Exemple #11
0
func Dial(netw, addr string, options *heroshi.RequestOptions) (net.Conn, error) {
	addrString, addrPort := heroshi.SplitPort(addr)
	var ip net.IP
	addrs, resolveTime, err := heroshi.ResolveName(addrString, NameServerAddress)
	if err != nil {
		log.Println("Dial: resolve error:", err.Error(), "in", resolveTime.String())
		return nil, err
	}
	if len(addrs) > 0 {
		ip = addrs[0]
		// log.Printf("Dial: resolved: %s -> %s in %s", addr, ip.String(), resolveTime.String())
		addr = ip.String()
	}
	if options != nil && options.Stat != nil {
		var tcpAddr net.TCPAddr
		tcpAddr.IP = ip
		options.Stat.RemoteAddr = &tcpAddr
		options.Stat.ResolveTime = resolveTime
	}

	// Return port back
	addr += ":" + addrPort

	var conn net.Conn
	if options != nil && options.ConnectTimeout != 0 {
		conn, err = net.DialTimeout(netw, addr, options.ConnectTimeout)
	} else {
		conn, err = net.Dial(netw, addr)
	}
	if err != nil {
		return conn, err
	}
	tcpConn, ok := conn.(*net.TCPConn)
	if !ok {
		return conn, errors.New("Dial: conn->TCPConn type assertion failed.")
	}
	tcpConn.SetKeepAlive(true)
	tcpConn.SetLinger(0)
	tcpConn.SetNoDelay(true)
	return tcpConn, err
}
Exemple #12
0
func server_A(ready chan int) {
	ch := []byte{0}
	var n int
	var listener net.TCPAddr
	listener.IP = net.ParseIP("127.0.0.1")
	listener.Port = 8888

	l, err := net.ListenTCP("tcp4", &listener)
	if err != nil {
		fmt.Printf("ListenTCP()  failed with err: %v\n", err)
		os.Exit(1)
	}
	defer l.Close()
	fmt.Printf("server() listener started ok, ready to accept TCP connections\n")
	ready <- 1 // send ready signal back to main()
	for {
		c, err := l.AcceptTCP()
		if err != nil {
			fmt.Printf("server() accept TCP failed with err: %v\n", err)
			os.Exit(1)
		}
		fmt.Printf("server() accepted TCP connection from client\n")
		n, err = c.Read(ch)
		if err != nil || n != 1 {
			fmt.Printf("server() read TCP failed with err: %v\n", err)
			os.Exit(1)
		}
		ch[0] *= 10 // modify input data and send it back
		n, err = c.Write(ch)
		if err != nil || n != 1 {
			fmt.Printf("server() write to TCP failed with err: %v\n", err)
			os.Exit(1)
		}
		fmt.Printf("server() wrote byte value = %d to TCP\n", ch)
		c.Close()
	}
}
Exemple #13
0
func (peer *Peer) connect() bool {
	debugl.Println("Calling connect(): ", peer)
	p := peer.torrent_peer
	dest_addr := new(net.TCPAddr)
	dest_addr.IP = net.ParseIP(p.ip)
	if dest_addr.IP == nil {
		errorl.Println("Couldn't get a valid IP")
		return false
	}
	dest_addr.Port = p.port

	var err error

	peer.connection, err = net.DialTCP("tcp", nil, dest_addr)
	if err != nil {
		errorl.Println("Couldn't connect: ", err)
		return false
	} else {
		debugl.Println("Connected to a peer: ", dest_addr.IP, dest_addr.Port)
	}
	peer.connection.SetKeepAlive(true)
	peer.connected = true
	return true
}
Exemple #14
0
func clientLoop(client *net.TCPConn) {
	addr := client.RemoteAddr()
	defer client.Close()

	var versionMethod [2]byte
	_, err := io.ReadFull(client, versionMethod[:])
	if err != nil {
		log.Printf("%v: Failed to read the version and methods number: %v", addr, err)
		return
	}

	if versionMethod[0] != 0x05 {
		log.Printf("%v: Only implemented socks5 proxy currently: %X.", addr, versionMethod[0])
		return
	}

	nMethods := versionMethod[1]
	if nMethods == 0 {
		log.Printf("%v: Must provide one method at least.", addr)
		return
	}

	methods := make([]byte, nMethods)
	_, err = io.ReadFull(client, methods)
	if err != nil {
		log.Printf("%v: Failed to read the methods: %v", addr, err)
		return
	}

	hasMethod0 := false
	for i := 0; i < int(nMethods); i++ {
		if methods[i] == 0x00 {
			hasMethod0 = true
			break
		}
	}
	if !hasMethod0 {
		log.Printf("%v: Only implemented 'no authentication required' method currently.", addr)
		return
	}

	versionMethod[1] = 0x00
	nw, err := client.Write(versionMethod[:])
	if err != nil || nw != len(versionMethod) {
		log.Printf("%v: Failed to write version and method back to the client: %v", addr, err)
		return
	}

	var requestHeader [4]byte
	_, err = io.ReadFull(client, requestHeader[:])
	if err != nil {
		log.Printf("%v: Failed to read the request header: %v", addr, err)
		return
	}

	var reply [22]byte
	reply[0] = 0x05 // VER
	reply[2] = 0x00 // RSV
	if requestHeader[0] != 0x05 {
		log.Printf("%v: Version number in the request does not match the previous one: %X", addr, requestHeader[0])
		return
	}
	if requestHeader[1] != 0x01 {
		log.Printf("%v: Only implemented CONNECT command currently.", addr)
		reply[1] = 0x07
		client.Write(reply[:4])
		return
	}
	if requestHeader[2] != 0x00 {
		log.Printf("%v: RESERVED field must be 0.", addr)
		return
	}

	remoteAddress := new(net.TCPAddr)
	switch requestHeader[3] {
	case 0x01, 0x04:
		{
			ipLen := 4 * requestHeader[3]
			buf := make([]byte, ipLen+2)
			_, err = io.ReadFull(client, buf)
			if err != nil {
				log.Printf("%v: Failed to read requested address: %v", addr, err)
				return
			}
			remoteAddress.IP = buf[:ipLen]
			remoteAddress.Port = int(buf[ipLen])<<8 + int(buf[ipLen+1])
			reply[3] = requestHeader[3]
		}
	case 0x03:
		{
			var hostLen [1]byte
			_, err = io.ReadFull(client, hostLen[:])
			if err != nil {
				log.Printf("%v: Failed to read requested host len: %v", addr, err)
				return
			}
			host := make([]byte, hostLen[0])
			_, err = io.ReadFull(client, host)
			if err != nil {
				log.Printf("%v: Failed to read requested host name: %v", addr, err)
				return
			}
			ips, err := net.LookupIP(string(host))
			if err != nil {
				log.Printf("%v: Failed to resolve requested host: %v", addr, err)
				return
			}
			if len(ips) == 0 {
				log.Printf("%v: There is no IP address corresponding to host '%s'.", addr, host)
				return
			}
			remoteAddress.IP = ips[0]
			reply[3] = len(ips[0]) / 4
			var port [2]byte
			_, err = io.ReadFull(client, port[:])
			if err != nil {
				log.Printf("%v: Failed to read requested port: %v", addr, err)
				return
			}
			remoteAddress.Port = int(port[0])<<8 + int(port[1])
		}
	default:
		log.Printf("%v: unknown address type: %X", addr, requestHeader[3])
		reply[1] = 0x08
		client.Write(reply[:4])
		return
	}
	log.Printf("%v: Requested address: %v", addr, remoteAddress)

	remote, err := net.DialTCP("tcp", nil, remoteAddress)
	if err != nil {
		log.Printf("%v: Failed to connect to the requested address: %v", addr, err)
		reply[1] = 0x05
		client.Write(reply[:6])
		return
	}
	defer remote.Close()

	reply[1] = 0x00
	ipEnd := 4 + 4*reply[3]
	copy(reply[4:ipEnd], remoteAddress.IP)
	reply[ipEnd] = byte(remoteAddress.Port >> 8)
	reply[ipEnd+1] = byte(remoteAddress.Port % 256)
	_, err = client.Write(reply[:ipEnd+2])
	if err != nil {
		log.Printf("%v: Failed to write reply: %v", addr, err)
		return
	}

	stopChan := make(chan bool)
	go readClientLoop(client, remote, stopChan)
	go readRemoteLoop(client, remote, stopChan)
	_ = <-stopChan
	_ = <-stopChan
}
Exemple #15
0
func main() {
	var err error
	flag.Parse()

	fmt.Printf("Blacksmith (%s)\n", version)
	fmt.Printf("  Commit:        %s\n", commit)
	fmt.Printf("  Build Time:    %s\n", buildTime)

	if *versionFlag {
		os.Exit(0)
	}

	// etcd config
	if etcdFlag == nil || clusterNameFlag == nil {
		fmt.Fprint(os.Stderr, "\nPlease specify the etcd endpoints\n")
		os.Exit(1)
	}

	// finding interface by interface name
	var dhcpIF *net.Interface
	if *listenIFFlag != "" {
		dhcpIF, err = net.InterfaceByName(*listenIFFlag)
		if err != nil {
			fmt.Fprintf(os.Stderr, "\nError while trying to get the interface (%s)\n", *listenIFFlag)
			os.Exit(1)
		}
	} else {
		fmt.Fprint(os.Stderr, "\nPlease specify an interface\n")
		os.Exit(1)
	}

	serverIP, err := interfaceIP(dhcpIF)
	if err != nil {
		fmt.Fprintf(os.Stderr, "\nError while trying to get the ip from the interface (%s)\n", dhcpIF)
		os.Exit(1)
	}

	webAddr := net.TCPAddr{IP: serverIP, Port: 8000}

	if *httpListenFlag != httpListenFlagDefaultTCPAddress {
		splitAddress := strings.Split(*httpListenFlag, ":")
		if len(splitAddress) > 2 {
			fmt.Printf("Incorrect tcp address provided: %s", httpListenFlag)
			os.Exit(1)
		}
		if len(splitAddress) == 1 {
			splitAddress = append(splitAddress, "8000")
		}

		webAddr.IP = net.ParseIP(splitAddress[0])
		port, err := strconv.ParseInt(splitAddress[1], 10, 64)

		if err != nil {
			fmt.Printf("Incorrect tcp address provided: %s", httpListenFlag)
			os.Exit(1)
		}
		webAddr.Port = int(port)

	}

	// component ports
	// web api is exposed to requests from `webIP', 0.0.0.0 by default

	// other services are exposed just through the given interface
	var httpBooterAddr = net.TCPAddr{IP: serverIP, Port: 70}
	var tftpAddr = net.UDPAddr{IP: serverIP, Port: 69}
	var pxeAddr = net.UDPAddr{IP: serverIP, Port: 4011}
	// 67 -> dhcp

	// dhcp setting
	leaseStart := net.ParseIP(*leaseStartFlag)
	leaseRange := *leaseRangeFlag
	leaseSubnet := net.ParseIP(*leaseSubnetFlag)
	leaseRouter := net.ParseIP(*leaseRouterFlag)

	dnsIPStrings := strings.Split(*dnsAddressesFlag, ",")
	if len(dnsIPStrings) == 0 {
		fmt.Fprint(os.Stderr, "\nPlease specify an DNS server\n")
		os.Exit(1)
	}
	for _, ipString := range dnsIPStrings {
		ip := net.ParseIP(ipString)
		if ip == nil {
			fmt.Fprintf(os.Stderr, "\nInvalid dns ip: %s\n", ipString)
			os.Exit(1)
		}
	}

	if leaseStart == nil {
		fmt.Fprint(os.Stderr, "\nPlease specify the lease start ip\n")
		os.Exit(1)
	}
	if leaseRange <= 1 {
		fmt.Fprint(os.Stderr, "\nLease range should be greater that 1\n")
		os.Exit(1)
	}
	if leaseSubnet == nil {
		fmt.Fprint(os.Stderr, "\nPlease specify the lease subnet\n")
		os.Exit(1)
	}
	if leaseRouter == nil {
		fmt.Fprint(os.Stderr, "\nNo network router is defined.\n")
	}

	fmt.Printf("Interface IP:    %s\n", serverIP.String())
	fmt.Printf("Interface Name:  %s\n", dhcpIF.Name)

	// datasources
	etcdClient, err := etcd.New(etcd.Config{
		Endpoints:               strings.Split(*etcdFlag, ","),
		HeaderTimeoutPerRequest: 5 * time.Second,
	})
	if err != nil {
		fmt.Fprintf(os.Stderr, "\nCouldn't create etcd connection: %s\n", err)
		os.Exit(1)
	}
	kapi := etcd.NewKeysAPI(etcdClient)

	v := datasource.BlacksmithVersion{
		Version:   version,
		Commit:    commit,
		BuildTime: buildTime,
	}
	etcdDataSource, err := datasource.NewEtcdDataSource(kapi, etcdClient,
		leaseStart, leaseRange, *clusterNameFlag, *workspacePathFlag,
		serverIP, dnsIPStrings, v)
	if err != nil {
		fmt.Fprintf(os.Stderr, "\nCouldn't create runtime configuration: %s\n", err)
		os.Exit(1)
	}

	go func() {
		logging.RecordLogs(log.New(os.Stderr, "", log.LstdFlags), *debugFlag)
	}()

	// serving api
	go func() {
		err := web.ServeWeb(etcdDataSource, webAddr)
		log.Fatalf("\nError while serving api: %s\n", err)
	}()

	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM)
	go func() {
		for _ = range c {
			gracefulShutdown(etcdDataSource)
		}
	}()

	// waiting til we're officially the master instance
	for !etcdDataSource.IsMaster() {
		logging.Debug(debugTag, "Not master, waiting to be promoted...")
		time.Sleep(datasource.StandbyMasterUpdateTime)
	}

	logging.Debug(debugTag, "Now we're the master instance. Starting the services...")

	// serving http booter
	go func() {
		err := pxe.ServeHTTPBooter(httpBooterAddr, etcdDataSource, webAddr.Port)
		log.Fatalf("\nError while serving http booter: %s\n", err)
	}()

	// serving tftp
	go func() {
		err := pxe.ServeTFTP(tftpAddr)
		log.Fatalf("\nError while serving tftp: %s\n", err)
	}()

	// pxe protocol
	go func() {
		err := pxe.ServePXE(pxeAddr, serverIP, httpBooterAddr)
		log.Fatalf("\nError while serving pxe: %s\n", err)
	}()

	// serving dhcp
	go func() {
		err := dhcp.ServeDHCP(&dhcp.DHCPSetting{
			IFName:     dhcpIF.Name,
			ServerIP:   serverIP,
			RouterAddr: leaseRouter,
			SubnetMask: leaseSubnet,
		}, etcdDataSource)
		log.Fatalf("\nError while serving dhcp: %s\n", err)
	}()

	for etcdDataSource.IsMaster() {
		time.Sleep(datasource.ActiveMasterUpdateTime)
	}

	logging.Debug(debugTag, "Now we're NOT the master. Terminating. Hoping to be restarted by the service manager.")

	gracefulShutdown(etcdDataSource)
}
// NewLocalServer creates a WebHookServer that listens on publicIP, publicPort
// and uses stateless-dns-server to obtain a hostname.
//
// If networkInterface is non-empty and localPort is non-zero then server will
// listen on the localPort for the given networkInterface. This is useful if
// running inside a container.
func NewLocalServer(
	publicIP []byte,
	publicPort int,
	networkInterface string,
	localPort int,
	subdomain, dnsSecret, tlsCert, tlsKey string,
	expiration time.Duration,
) (*LocalServer, error) {
	s := &LocalServer{
		hooks: make(map[string]http.Handler),
	}

	// Address that we should be listening on
	localAddress := net.TCPAddr{
		IP:   publicIP,
		Port: publicPort,
	}
	if localPort != 0 {
		localAddress.Port = localPort
	}

	// If network interface is specified we listen to that, instead of the public
	// IP address. This is necessary when running inside a docker container where
	// the local network interface isn't assigned to a public IP.
	if networkInterface != "" {
		iface, err := net.InterfaceByName(networkInterface)
		if err != nil {
			return nil, fmt.Errorf(
				"Unable to find interface: %s, error: %s", networkInterface, err,
			)
		}
		addrs, err := iface.Addrs()
		if err != nil {
			return nil, fmt.Errorf(
				"Couldn't list addresses of interface: %s, error: %s", networkInterface, err,
			)
		}
		gotIP := false
		for _, addr := range addrs {
			if a, ok := addr.(*net.IPNet); ok && a.IP.To4() != nil {
				localAddress.IP = a.IP.To4()
				gotIP = true
				break
			}
		}
		if !gotIP {
			return nil, fmt.Errorf("Interface: %s has no IPv4 address", networkInterface)
		}
	}

	// Setup server
	s.server = &graceful.Server{
		Timeout: 35 * time.Second,
		Server: &http.Server{
			Addr:    localAddress.String(),
			Handler: http.HandlerFunc(s.handle),
		},
		NoSignalHandling: true,
	}

	// Setup server TLS configuration
	if tlsCert != "" && tlsKey != "" {
		cert, err := tls.X509KeyPair(
			[]byte(tlsCert),
			[]byte(tlsKey),
		)
		if err != nil {
			return nil, err
		}
		s.server.TLSConfig = &tls.Config{
			NextProtos:   []string{"http/1.1"},
			Certificates: []tls.Certificate{cert},
		}
	}

	// Construct hostname (using stateless-dns-go)
	host := hostname.New(
		publicIP,
		subdomain,
		time.Now().Add(expiration),
		dnsSecret,
	)

	// Construct URL
	proto := "http"
	port := ""
	if s.server.TLSConfig != nil {
		proto = "https"
		if publicPort != 443 {
			port = fmt.Sprintf(":%d", publicPort)
		}
	} else {
		if publicPort != 80 {
			port = fmt.Sprintf(":%d", publicPort)
		}
	}
	s.url = proto + "://" + host + port + "/"

	return s, nil
}
Exemple #17
0
func main() {
	var err error
	flag.Parse()

	fmt.Printf("Blacksmith (%s)\n", version)
	fmt.Printf("  Commit:        %s\n", commit)
	fmt.Printf("  Build Time:    %s\n", buildTime)

	if *versionFlag {
		os.Exit(0)
	}

	if *debugFlag {
		log.SetLevel(log.DebugLevel)
	} else {
		log.SetLevel(log.InfoLevel)
	}

	// etcd config
	if etcdFlag == nil || clusterNameFlag == nil {
		fmt.Fprint(os.Stderr, "\nPlease specify the etcd endpoints\n")
		os.Exit(1)
	}

	// finding interface by interface name
	var dhcpIF *net.Interface
	if *listenIFFlag != "" {
		dhcpIF, err = net.InterfaceByName(*listenIFFlag)
		if err != nil {
			fmt.Fprintf(os.Stderr, "\nError while trying to get the interface (%s): %s\n", *listenIFFlag, err)
			os.Exit(1)
		}
	} else {
		fmt.Fprint(os.Stderr, "\nPlease specify an interface\n")
		os.Exit(1)
	}

	serverIP, err := interfaceIP(dhcpIF)
	if err != nil {
		fmt.Fprintf(os.Stderr, "\nError while trying to get the ip from the interface (%v)\n", dhcpIF)
		os.Exit(1)
	}

	// web api can be configured to listen on a custom address
	webAddr := net.TCPAddr{IP: serverIP, Port: 8000}
	if *httpListenFlag != httpListenFlagDefaultTCPAddress {
		splitAddress := strings.Split(*httpListenFlag, ":")
		if len(splitAddress) > 2 {
			fmt.Printf("Incorrect tcp address provided: %s\n", *httpListenFlag)
			os.Exit(1)
		}
		if len(splitAddress) == 1 {
			splitAddress = append(splitAddress, "8000")
		}

		webAddr.IP = net.ParseIP(splitAddress[0])
		port, err := strconv.ParseInt(splitAddress[1], 10, 64)

		if err != nil {
			fmt.Printf("Incorrect tcp address provided: %s\n", *httpListenFlag)
			os.Exit(1)
		}
		webAddr.Port = int(port)
	}

	// other services are exposed just through the given interface, on hard coded ports
	var httpBooterAddr = net.TCPAddr{IP: serverIP, Port: 70}
	var tftpAddr = net.UDPAddr{IP: serverIP, Port: 69}
	var pxeAddr = net.UDPAddr{IP: serverIP, Port: 4011}
	// 67 -> dhcp

	// dhcp setting
	leaseStart := net.ParseIP(*leaseStartFlag)
	leaseRange := *leaseRangeFlag

	dnsIPStrings := strings.Split(*dnsAddressesFlag, ",")
	if len(dnsIPStrings) == 0 {
		fmt.Fprint(os.Stderr, "\nPlease specify an DNS server\n")
		os.Exit(1)
	}
	for _, ipString := range dnsIPStrings {
		ip := net.ParseIP(ipString)
		if ip == nil {
			fmt.Fprintf(os.Stderr, "\nInvalid dns ip: %s\n", ipString)
			os.Exit(1)
		}
	}

	if leaseStart == nil {
		fmt.Fprint(os.Stderr, "\nPlease specify the lease start ip\n")
		os.Exit(1)
	}
	if leaseRange <= 1 {
		fmt.Fprint(os.Stderr, "\nLease range should be greater that 1\n")
		os.Exit(1)
	}

	fmt.Printf("Interface IP:    %s\n", serverIP.String())
	fmt.Printf("Interface Name:  %s\n", dhcpIF.Name)

	// datasources
	etcdClient, err := etcd.New(etcd.Config{
		Endpoints:               strings.Split(*etcdFlag, ","),
		HeaderTimeoutPerRequest: 5 * time.Second,
	})
	if err != nil {
		fmt.Fprintf(os.Stderr, "\nCouldn't create etcd connection: %s\n", err)
		os.Exit(1)
	}
	kapi := etcd.NewKeysAPI(etcdClient)

	selfInfo := datasource.InstanceInfo{
		IP:               serverIP,
		Nic:              dhcpIF.HardwareAddr,
		WebPort:          webAddr.Port,
		Version:          version,
		Commit:           commit,
		BuildTime:        buildTime,
		ServiceStartTime: time.Now().UTC().Unix(),
	}
	etcdDataSource, err := datasource.NewEtcdDataSource(kapi, etcdClient,
		leaseStart, leaseRange, *clusterNameFlag, *workspacePathFlag,
		dnsIPStrings, selfInfo)
	if err != nil {
		fmt.Fprintf(os.Stderr, "\nCouldn't create runtime configuration: %s\n", err)
		os.Exit(1)
	}

	// serving api
	go func() {
		err := web.ServeWeb(etcdDataSource, webAddr)
		log.Fatalf("\nError while serving api: %s\n", err)
	}()

	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM)
	go func() {
		for _ = range c {
			gracefulShutdown(etcdDataSource)
		}
	}()

	// waiting till we're officially the master instance
	for etcdDataSource.WhileMaster() != nil {
		log.WithFields(log.Fields{
			"where":  "blacksmith.main",
			"action": "debug",
		}).Debug("Not master, waiting to be promoted...")
		time.Sleep(datasource.StandbyMasterUpdateTime)
	}

	log.WithFields(log.Fields{
		"where":  "blacksmith.main",
		"action": "debug",
	}).Debug("Now we're the master instance. Starting the services...")

	// serving http booter
	go func() {
		err := pxe.ServeHTTPBooter(httpBooterAddr, etcdDataSource, webAddr.Port)
		log.Fatalf("\nError while serving http booter: %s\n", err)
	}()

	// serving tftp
	go func() {
		err := pxe.ServeTFTP(tftpAddr)
		log.Fatalf("\nError while serving tftp: %s\n", err)
	}()

	// pxe protocol
	go func() {
		err := pxe.ServePXE(pxeAddr, serverIP, httpBooterAddr)
		log.Fatalf("\nError while serving pxe: %s\n", err)
	}()

	// serving dhcp
	go func() {
		err := dhcp.StartDHCP(dhcpIF.Name, serverIP, etcdDataSource)
		log.Fatalf("\nError while serving dhcp: %s\n", err)
	}()

	for etcdDataSource.WhileMaster() == nil {
		time.Sleep(datasource.ActiveMasterUpdateTime)
	}

	log.WithFields(log.Fields{
		"where":  "blacksmith.main",
		"action": "debug",
	}).Debug("Now we're NOT the master. Terminating. Hoping to be restarted by the service manager.")

	gracefulShutdown(etcdDataSource)
}
func ProxyRelay(port string, relays map[string]Relay) error {
	tcpAddr := net.TCPAddr{}
	tcpAddr.IP = net.ParseIP("127.0.0.1")
	tcpAddr.Port, _ = strconv.Atoi(port)
	ln, err := net.ListenTCP("tcp", &tcpAddr)
	if err != nil {
		msg := fmt.Sprintf("Proxy listener error on port %s: %s",
			port, err)
		LogWriter.Err(msg)
		return fmt.Errorf(msg)
	}
	msg := fmt.Sprintf("Started proxy listener on port: %s",
		port)
	LogWriter.Info(msg)
	defer ln.Close()
	for {
		conn, err := ln.AcceptTCP()
		if err != nil {
			msg := fmt.Sprintf("Error accepting TCP connection on port %s: %s",
				port, err)
			LogWriter.Err(msg)
			continue
		}
		conn.SetKeepAlive(true)
		if err != nil {
			msg := fmt.Sprintf("Error setting keep-alive on connection: %s",
				err)
			LogWriter.Err(msg)
		}
		go acceptClient(conn, relays)
	}
	return nil
}