LoginSignup
17
14

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