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);
}