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 } } }
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 }
// 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 }
// 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 }
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])) }
// 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 }
// 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 }
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 }
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") }
// 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) } }
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) }
// 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 }
// 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) }
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 } }
// 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 }
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 }
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) } }
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 }
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() } }
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 }
// 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 }
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 (cm *connectionMaker) completeAddr(addr net.TCPAddr) string { if addr.Port == 0 { addr.Port = cm.port } return addr.String() }
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 }
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) }