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