17
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

GoのgRPCでRemote IPを取得する方法

Posted at

結論

contextの中にpeerの情報があるのでそこにnet.Addrが入っている。

import (
	"google.golang.org/grpc/peer"
)

func foo(ctx context.Context, ...) {
	var addr string
	if pr, ok := peer.FromContext(ctx); ok {
		addr = pr.Addr.String()
	}
}

詳細

gRPCのgo実装であるgrpc-goはサーバ側でリクエストを受け取ってprotobufで生成されたハンドラを呼び出す部分とhttp2自体の実装部分とに分かれています。前者はserver.go、後者はhtt2_server.goになります。

Remote IPは接続元の情報(Peer)としてhttp2の実装側でstreamの中のcontextに格納されています。格納しているのはここ

あとはハンドラの第一引数としてcontext.Contextが渡されるのでpeer.FromContext(ctx)でPeerを取得します。peerのAddrがnet.AddrなのでそのままString()でも良いですが、IPアドレスのみを取得したい場合は*net.TCPAddrに変換すると良いでしょう。

import (
	"google.golang.org/grpc/peer"
)

func (s *EchoServer) Echo(ctx context.Context, in *echo.EchoRequest) (*echo.EchoResponse, error) {
	var addr string
	if pr, ok := peer.FromContext(ctx); ok {
		if tcpAddr, ok := pr.Addr.(*net.TCPAddr); ok {
			addr = tcpAddr.IP.String()
		} else {
			addr = pr.Addr.String()
		}
	}
	log.Printf("remote addr: %v", addr)

	return &echo.EchoResponse{Message: in.Message}, nil
}
17
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?