2016-11-10 12:39:25 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* odissey.
|
|
|
|
*
|
|
|
|
* PostgreSQL connection pooler and request router.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
2016-11-15 11:38:31 +00:00
|
|
|
#include <stdarg.h>
|
2016-11-10 12:39:25 +00:00
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2016-12-13 15:26:37 +00:00
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
|
2016-11-25 12:38:52 +00:00
|
|
|
#include <machinarium.h>
|
2016-11-10 12:39:25 +00:00
|
|
|
#include <soprano.h>
|
|
|
|
|
|
|
|
#include "od_macro.h"
|
2016-11-28 13:03:09 +00:00
|
|
|
#include "od_pid.h"
|
2016-11-28 14:47:39 +00:00
|
|
|
#include "od_syslog.h"
|
2016-11-10 12:39:25 +00:00
|
|
|
#include "od_log.h"
|
2016-11-14 10:18:27 +00:00
|
|
|
#include "od_io.h"
|
2016-11-10 12:39:25 +00:00
|
|
|
|
2017-03-23 12:55:36 +00:00
|
|
|
int od_read(machine_io_t io, so_stream_t *stream, int time_ms)
|
2016-11-10 12:39:25 +00:00
|
|
|
{
|
2017-04-21 10:09:21 +00:00
|
|
|
uint32_t request_start = so_stream_used(stream);
|
|
|
|
uint32_t request_size = 0;
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
uint8_t *request_data = stream->s + request_start;
|
2016-11-10 12:39:25 +00:00
|
|
|
uint32_t len;
|
|
|
|
int to_read;
|
2017-04-21 10:09:21 +00:00
|
|
|
to_read = so_read(&len, &request_data, &request_size);
|
2016-11-10 12:39:25 +00:00
|
|
|
if (to_read == 0)
|
|
|
|
break;
|
|
|
|
if (to_read == -1)
|
|
|
|
return -1;
|
|
|
|
int rc = so_stream_ensure(stream, to_read);
|
|
|
|
if (rc == -1)
|
|
|
|
return -1;
|
2017-03-31 14:17:17 +00:00
|
|
|
rc = machine_read(io, (char*)stream->p, to_read, time_ms);
|
2016-11-10 12:39:25 +00:00
|
|
|
if (rc < 0)
|
|
|
|
return -1;
|
|
|
|
so_stream_advance(stream, to_read);
|
2017-04-21 10:09:21 +00:00
|
|
|
request_size += to_read;
|
2016-11-10 12:39:25 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2016-11-14 10:24:37 +00:00
|
|
|
|
2017-03-23 12:55:36 +00:00
|
|
|
int od_write(machine_io_t io, so_stream_t *stream)
|
2016-11-14 10:24:37 +00:00
|
|
|
{
|
|
|
|
int rc;
|
2017-04-20 12:26:13 +00:00
|
|
|
rc = machine_write(io, (char*)stream->s, so_stream_used(stream), INT_MAX);
|
2016-11-14 10:24:37 +00:00
|
|
|
if (rc < 0)
|
|
|
|
return -1;
|
|
|
|
return 0;
|
|
|
|
}
|
2016-12-13 15:26:37 +00:00
|
|
|
|
2017-03-23 12:55:36 +00:00
|
|
|
char *od_getpeername(machine_io_t io)
|
2016-12-13 15:26:37 +00:00
|
|
|
{
|
|
|
|
static char sockname[128];
|
2016-12-14 13:45:38 +00:00
|
|
|
char addr[128];
|
2016-12-13 15:26:37 +00:00
|
|
|
struct sockaddr_storage sa;
|
|
|
|
int salen = sizeof(sa);
|
2017-03-23 12:55:36 +00:00
|
|
|
int rc = machine_getpeername(io, (struct sockaddr*)&sa, &salen);
|
2016-12-13 15:26:37 +00:00
|
|
|
if (rc < 0)
|
|
|
|
goto unknown;
|
|
|
|
if (sa.ss_family == AF_INET) {
|
|
|
|
struct sockaddr_in *sin = (struct sockaddr_in*)&sa;
|
2016-12-14 13:45:38 +00:00
|
|
|
inet_ntop(sa.ss_family, &sin->sin_addr, addr, sizeof(addr));
|
|
|
|
snprintf(sockname, sizeof(sockname), "%s:%d", addr, ntohs(sin->sin_port));
|
|
|
|
} else
|
2016-12-13 15:26:37 +00:00
|
|
|
if (sa.ss_family == AF_INET6) {
|
2016-12-14 13:45:38 +00:00
|
|
|
struct sockaddr_in6 *sin = (struct sockaddr_in6*)&sa;
|
|
|
|
inet_ntop(sa.ss_family, &sin->sin6_addr, addr, sizeof(addr));
|
2017-03-03 13:13:51 +00:00
|
|
|
snprintf(sockname, sizeof(sockname), "[%s]:%d", addr, ntohs(sin->sin6_port));
|
2016-12-14 13:45:38 +00:00
|
|
|
} else {
|
|
|
|
goto unknown;
|
2016-12-13 15:26:37 +00:00
|
|
|
}
|
2016-12-14 13:45:38 +00:00
|
|
|
return sockname;
|
2016-12-13 15:26:37 +00:00
|
|
|
unknown:
|
|
|
|
snprintf(sockname, sizeof(sockname), "unknown");
|
|
|
|
return sockname;
|
|
|
|
}
|