Report abuse


			
OBJECT ffi_getpeername(STATE, int s, int reverse_lookup) {
  OBJECT host;
  OBJECT address;

  int error = 0;

  struct sockaddr_storage addr;
  socklen_t len = sizeof addr;

  char hbuf[1024];
  char pbuf[1024];

  error = getpeername(s, (struct sockaddr*)&addr, &len);
  if(error) {
    printf("ffi_getpeername ERROR: %s\n", gai_strerror(error));
    return Qnil;
  }

  // Get the numeric name info
  error = getnameinfo((struct sockaddr*)&addr, len, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV);
  if(error) {
    printf("ffi_getpeername ERROR: %s\n", gai_strerror(error));
    return Qnil;
  }
  address = string_new(state, hbuf);

  if(reverse_lookup) {
    // Resolve the DNS name
    error = getnameinfo((struct sockaddr*)&addr, len, hbuf, sizeof(hbuf), NULL, 0, 0);
    if(error) {
      printf("ffi_getpeername ERROR: %s\n", gai_strerror(error));
      return Qnil;
    }

  }
  host = string_new(state, hbuf);
  // Return the two addresses as a tuple of Rubinius strings
  return tuple_new2(state, 2, host, address);
}