Пример #1
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
		}
	}
}
Пример #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
}
Пример #3
0
// ListenTCP requests the remote peer open a listening socket
// on laddr. Incoming connections will be available by calling
// Accept on the returned net.Listener.
func (c *ClientConn) ListenTCP(laddr *net.TCPAddr) (net.Listener, error) {
	m := channelForwardMsg{
		"tcpip-forward",
		true, // sendGlobalRequest waits for a reply
		laddr.IP.String(),
		uint32(laddr.Port),
	}
	// send message
	resp, err := c.sendGlobalRequest(m)
	if err != nil {
		return nil, err
	}

	// If the original port was 0, then the remote side will
	// supply a real port number in the response.
	if laddr.Port == 0 {
		port, _, ok := parseUint32(resp.Data)
		if !ok {
			return nil, errors.New("unable to parse response")
		}
		laddr.Port = int(port)
	}

	// Register this forward, using the port number we obtained.
	//
	// This does not work on OpenSSH < 6.0, which will send a
	// ChannelOpenMsg with port number 0, rather than the actual
	// port number.
	ch := c.forwardList.add(*laddr)

	return &tcpListener{laddr, c, ch}, nil
}
Пример #4
0
// ListenTCP requests the remote peer open a listening socket
// on laddr. Incoming connections will be available by calling
// Accept on the returned net.Listener.
func (c *ClientConn) ListenTCP(laddr *net.TCPAddr) (net.Listener, error) {
	if laddr.Port == 0 && isBrokenOpenSSHVersion(c.serverVersion) {
		return c.autoPortListenWorkaround(laddr)
	}

	m := channelForwardMsg{
		"tcpip-forward",
		true, // sendGlobalRequest waits for a reply
		laddr.IP.String(),
		uint32(laddr.Port),
	}
	// send message
	resp, err := c.sendGlobalRequest(m)
	if err != nil {
		return nil, err
	}

	// If the original port was 0, then the remote side will
	// supply a real port number in the response.
	if laddr.Port == 0 {
		port, _, ok := parseUint32(resp.Data)
		if !ok {
			return nil, errors.New("unable to parse response")
		}
		laddr.Port = int(port)
	}

	// Register this forward, using the port number we obtained.
	ch := c.forwardList.add(*laddr)

	return &tcpListener{laddr, c, ch}, nil
}
Пример #5
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]))
}
Пример #6
0
// ListenTCP requests the remote peer open a listening socket
// on laddr. Incoming connections will be available by calling
// Accept on the returned net.Listener.
func (c *ClientConn) ListenTCP(laddr *net.TCPAddr) (net.Listener, error) {
	m := channelForwardMsg{
		"tcpip-forward",
		true, // sendGlobalRequest waits for a reply
		laddr.IP.String(),
		uint32(laddr.Port),
	}
	// send message
	resp, err := c.sendGlobalRequest(m)
	if err != nil {
		return nil, err
	}
	// fixup laddr. If the original port was 0, then the remote side will
	// supply one in the resp.
	if laddr.Port == 0 {
		port, _, ok := parseUint32(resp.Data)
		if !ok {
			return nil, errors.New("unable to parse response")
		}
		laddr.Port = int(port)
	}

	// register this forward
	ch := c.forwardList.add(laddr)
	return &tcpListener{laddr, c, ch}, nil
}
Пример #7
0
// ListenTCP requests the remote peer open a listening socket
// on laddr. Incoming connections will be available by calling
// Accept on the returned net.Listener.
func (c *Client) ListenTCP(laddr *net.TCPAddr) (net.Listener, error) {
	if laddr.Port == 0 && isBrokenOpenSSHVersion(string(c.ServerVersion())) {
		return c.autoPortListenWorkaround(laddr)
	}

	m := channelForwardMsg{
		laddr.IP.String(),
		uint32(laddr.Port),
	}
	// send message
	ok, resp, err := c.SendRequest("tcpip-forward", true, Marshal(&m))
	if err != nil {
		return nil, err
	}
	if !ok {
		return nil, errors.New("ssh: tcpip-forward request denied by peer")
	}

	// If the original port was 0, then the remote side will
	// supply a real port number in the response.
	if laddr.Port == 0 {
		var p struct {
			Port uint32
		}
		if err := Unmarshal(resp, &p); err != nil {
			return nil, err
		}
		laddr.Port = int(p.Port)
	}

	// Register this forward, using the port number we obtained.
	ch := c.forwards.add(*laddr)

	return &tcpListener{laddr, c, ch}, nil
}
Пример #8
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

}
Пример #9
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")

}
Пример #10
0
// Start a webserver serving files from the given path. Take the address given and attach the HTTP
// server to a random port. If portCh is non-nil, sends the chosen port on this channel.
func webserver(path string, addr net.TCPAddr, portCh chan int) {
	addr.Port = 0
	listener, err := net.ListenTCP("tcp", &addr)
	if portCh != nil {
		portCh <- listener.Addr().(*net.TCPAddr).Port
	}

	log.Printf("webserver listening on: %s", listener.Addr())
	err = http.Serve(listener, http.FileServer(http.Dir(path)))
	if err != nil {
		panic(err)
	}
}
Пример #11
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)
}
Пример #12
0
// Opens a TCP server socket and returns a stream listener, ready to accept. If
// an auto-port (0) is requested, the port is updated in the argument.
func Listen(addr *net.TCPAddr) (*Listener, error) {
	// Open the server socket
	sock, err := net.ListenTCP("tcp", addr)
	if err != nil {
		return nil, err
	}
	addr.Port = sock.Addr().(*net.TCPAddr).Port

	// Initialize and return the listener
	return &Listener{
		socket: sock,
		Sink:   make(chan *Stream),
		quit:   make(chan chan error),
	}, nil
}
Пример #13
0
// autoPortListenWorkaround simulates automatic port allocation by
// trying random ports repeatedly.
func (c *Client) autoPortListenWorkaround(laddr *net.TCPAddr) (net.Listener, error) {
	var sshListener net.Listener
	var err error
	const tries = 10
	for i := 0; i < tries; i++ {
		addr := *laddr
		addr.Port = 1024 + portRandomizer.Intn(60000)
		sshListener, err = c.ListenTCP(&addr)
		if err == nil {
			laddr.Port = addr.Port
			return sshListener, err
		}
	}
	return nil, fmt.Errorf("ssh: listen on random port failed after %d tries: %v", tries, err)
}
Пример #14
0
func main() {

	fmt.Printf("Hello, 世界\n")

	// socket einrichten und auf verbindung warten
	var listenAddr *net.TCPAddr = new(net.TCPAddr)
	listenAddr.Port = INPORT
	listenSock, err := net.ListenTCP("tcp4", listenAddr)
	if err != nil {
		fmt.Printf(err.String())
	}

	for {
		//establisch connection
		conn, _ := listenSock.AcceptTCP()
		go handleConnection(conn) // add 'go' to allow multiple connections
	}
}
Пример #15
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

}
Пример #16
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
}
Пример #17
0
func ListenLetter(ch chan error) {
	var addr net.TCPAddr
	addr.Port = Port
	ls, err := net.ListenTCP("tcp", &addr)
	if err != nil {
		ch <- err
		return
	}
	ch <- nil
	cc := make(chan error)
	go HandleErr(cc)
	for {
		c, err := ls.AcceptTCP()
		if err != nil {
			time.Sleep(time.Second)
			continue
		}
		go SendLetter(c, cc)
	}
}
Пример #18
0
func main() {
	addr := new(net.TCPAddr)
	addr.Port = 2300
	srv, err := net.ListenTCP("tcp", addr)
	if err != nil {
		fmt.Println("error listening on port 23")
		fmt.Println(err)
		return
	}
	for {
		fmt.Println("waiting for connection...")
		conn, err := srv.AcceptTCP()
		if err != nil {
			fmt.Println("error accepting connection")
			continue
		}
		fmt.Println("connection accepted")
		//connected := make(chan bool)
		session(conn)
		//<-connected
	}
}
func GetInfo(fingerprint string) *net.TCPAddr {

	ri := customtypes.RequestInfo{fingerprint}
	var annMsg customtypes.AnnounceMsg
	annMsg.Payload = ri
	annMsg.Kind = "ri"

	annMsgBytes, err := json.Marshal(annMsg)
	CheckError(err)

	listenConn.WriteToUDP(annMsgBytes, serverUDPAddr)

	readBytes := make([]byte, 1024)
	n, _, err := listenConn.ReadFromUDP(readBytes)
	CheckError(err)

	var readMsg net.TCPAddr
	err = json.Unmarshal(readBytes[0:n], &readMsg)
	readMsg.Port = tcpPort
	CheckError(err)

	return &readMsg
}
Пример #20
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()
	}
}
Пример #21
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
}
Пример #22
0
// 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
}
Пример #23
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)
}
Пример #24
0
func (cm *connectionMaker) completeAddr(addr net.TCPAddr) string {
	if addr.Port == 0 {
		addr.Port = cm.port
	}
	return addr.String()
}
Пример #25
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
}
Пример #26
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)
}