Skip to content

Why does connection to localhost fail on local ? #7429

@manuraj17

Description

@manuraj17

I faced this issue when I was testing out a simple application; Not able to put a finger on what exactly am missing.

My client code is returning with this error

could not greet: rpc error: code = DeadlineExceeded desc = context deadline exceeded

I have my server running as

const (
	port = ":50051"
)

// server is used to implement helloworld.GreeterServer.
type server struct {
	helloworld.UnimplementedGreeterServer
}

// SayHello implements helloworld.GreeterServer
func (s *server) SayHello(ctx context.Context, in *helloworld.HelloRequest) (*helloworld.HelloReply, error) {
	log.Printf("Received: %v\n", in.GetName())
	return &helloworld.HelloReply{Message: "Hello " + in.Name}, nil
}

func main() {
	lis, err := net.Listen("tcp", port)
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
	}
	s := grpc.NewServer()
	helloworld.RegisterGreeterServer(s, &server{})
	log.Printf("server starting at %v\n", lis.Addr())
	if err := s.Serve(lis); err != nil {
		log.Fatalf("failed to serve: %v", err)
	}
}

Client connecting to localhost as

const (
	address = "localhost:50051"
	// address     = "[::1]:50051"

	// address     = "127.0.0.1:50051"
	defaultName = "world"
)

func main() {
	// Set up a connection to the server.
	conn, err := grpc.NewClient(address, grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}
	defer conn.Close()
	c := helloworld.NewGreeterClient(conn)

	// Contact the server and print out its response.
	name := defaultName
	if len(os.Args) > 1 {
		name = os.Args[1]
	}
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	r, err := c.SayHello(ctx, &helloworld.HelloRequest{Name: name})
	if err != nil {
		log.Fatalf("could not greet: %v", err)
	}
	log.Printf("Greeting: %s", r.GetMessage())
}

This code fails.

But when I connect with either of

	address     = "[::1]:50051"
	address     = "127.0.0.1:50051"

It works. I am trying to understand what am missing here. Can anyone help me understand? TIA!

Full application code available here

UPDATE (More Info):

Some more information
Version

google.golang.org/grpc v1.65.0

I am able to connect if I am using 127.0.0.0 and [::1]
The issue specifically seems to occur when localhost is used.

etc/hosts is below

##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting.  Do not change this entry.
##
127.0.0.1       localhost
127.0.0.1       mail.local
255.255.255.255 broadcasthost
::1             localhost

I am running the server at add = :50051 and initialising like

	lis, err := net.Listen("tcp", port)

It works with Dial

When I use Dial it works

	conn, err := grpc.DialContext(ctx, addr,
		grpc.WithTransportCredentials(insecure.NewCredentials()),
		grpc.WithBlock(),
	)

I have tried all variations to connect without using Dial, and everything except localhost works. The resolution of localhost also seems to be working correctly. I get the following logs

 localhost resolves to: [::1 127.0.0.1]

NOTE: IPV6 gets resolved first.

Though I am not able to figure what failed here. I will have end up not using localhost for now. Though, curious what is happening here.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions