|
@@ -30,27 +30,29 @@
|
|
|
#include "log.h"
|
|
|
|
|
|
|
|
|
-
|
|
|
#define NETBUFSIZE 200
|
|
|
#define DEFAULT_BINDADDR "0.0.0.0"
|
|
|
#define DEFAULT_PORT 5574
|
|
|
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-void print_usage(char *program) {
|
|
|
+void print_usage(char *program)
|
|
|
+{
|
|
|
set_log_level(LOG_INFO);
|
|
|
LINFO("version: pdb_server %d\n", PDB_VERSION);
|
|
|
- LINFO("Listens on a UDP port for queries and sends answer UDP packets back.\n");
|
|
|
+ LINFO("Listens on a UDP port for queries and sends answer UDP packets "
|
|
|
+ "back.\n");
|
|
|
LINFO("\n");
|
|
|
LINFO("Usage: %s [<option>...]\n", program);
|
|
|
- LINFO(" %s -m <data file> [-i <bind addr>] [-p <port>] [-d <log level>]\n", program);
|
|
|
+ LINFO(" %s -m <data file> [-i <bind addr>] [-p <port>] [-d <log level>]\n",
|
|
|
+ program);
|
|
|
LINFO("\n");
|
|
|
LINFO(" Options:\n");
|
|
|
LINFO(" -m <file>: Specifies the file containing the backend data.\n");
|
|
|
- LINFO(" -i <bind addr>: Specifies the address to bind the UDP socket to.\n");
|
|
|
+ LINFO(" -i <bind addr>: Specifies the address to bind the UDP socket "
|
|
|
+ "to.\n");
|
|
|
LINFO(" Default is '%s'.\n", DEFAULT_BINDADDR);
|
|
|
- LINFO(" -p <port>: Specifies the port to listen at in udp_server mode.\n");
|
|
|
+ LINFO(" -p <port>: Specifies the port to listen at in udp_server "
|
|
|
+ "mode.\n");
|
|
|
LINFO(" Default is %ld.\n", (long int)DEFAULT_PORT);
|
|
|
LINFO(" -d <debug level>: %ld for debug level.\n", LOG_DEBUG);
|
|
|
LINFO(" %ld for info level.\n", LOG_INFO);
|
|
@@ -60,34 +62,39 @@ void print_usage(char *program) {
|
|
|
LINFO(" %ld for critical level.\n", LOG_CRIT);
|
|
|
LINFO(" %ld for alert level.\n", LOG_ALERT);
|
|
|
LINFO(" %ld for emergency level.\n", LOG_EMERG);
|
|
|
- LINFO(" %ld to disable all messages.\n", LOG_EMERG-1);
|
|
|
+ LINFO(" %ld to disable all messages.\n",
|
|
|
+ LOG_EMERG - 1);
|
|
|
LINFO(" Default is warning level.\n");
|
|
|
LINFO(" -v: Print the version\n");
|
|
|
LINFO(" -h: Print this help.\n");
|
|
|
}
|
|
|
|
|
|
-int pdb_msg_server_send(int so, char *buf, size_t answerlen, struct sockaddr *fromaddr, socklen_t fromaddrlen)
|
|
|
+int pdb_msg_server_send(int so, char *buf, size_t answerlen,
|
|
|
+ struct sockaddr *fromaddr, socklen_t fromaddrlen)
|
|
|
{
|
|
|
ssize_t bytes_sent;
|
|
|
int try = 0;
|
|
|
- again:
|
|
|
- bytes_sent = sendto(so, buf, answerlen, 0, fromaddr, fromaddrlen);
|
|
|
- if (bytes_sent < 3) {
|
|
|
- if ((errno == EINTR) && (try < 3)) {
|
|
|
- try++;
|
|
|
- LERR("sendto() failed - trying again. errno=%d (%s)\n", errno, strerror(errno));
|
|
|
- goto again;
|
|
|
- }
|
|
|
- LERR("sendto() failed with errno=%d (%s)\n", errno, strerror(errno));
|
|
|
- if ((errno==EAGAIN)||(errno==EINTR)||(errno==EWOULDBLOCK)) return 0;
|
|
|
- return -1;
|
|
|
+again:
|
|
|
+ bytes_sent = sendto(so, buf, answerlen, 0, fromaddr, fromaddrlen);
|
|
|
+ if(bytes_sent < 3) {
|
|
|
+ if((errno == EINTR) && (try < 3)) {
|
|
|
+ try++;
|
|
|
+ LERR("sendto() failed - trying again. errno=%d (%s)\n", errno,
|
|
|
+ strerror(errno));
|
|
|
+ goto again;
|
|
|
}
|
|
|
- if (bytes_sent != answerlen) {
|
|
|
- LERR("cannot send the whole answer (%ld/%ld).\n", (long int)bytes_sent, (long int)answerlen);
|
|
|
+ LERR("sendto() failed with errno=%d (%s)\n", errno, strerror(errno));
|
|
|
+ if((errno == EAGAIN) || (errno == EINTR) || (errno == EWOULDBLOCK))
|
|
|
return 0;
|
|
|
- }
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ if(bytes_sent != answerlen) {
|
|
|
+ LERR("cannot send the whole answer (%ld/%ld).\n", (long int)bytes_sent,
|
|
|
+ (long int)answerlen);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
|
|
|
- return 0;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -100,7 +107,7 @@ int pdb_msg_server_send(int so, char *buf, size_t answerlen, struct sockaddr *fr
|
|
|
*/
|
|
|
int udp_server(int so)
|
|
|
{
|
|
|
- struct pdb_msg msg;
|
|
|
+ struct pdb_msg msg;
|
|
|
struct sockaddr fromaddr;
|
|
|
socklen_t fromaddrlen;
|
|
|
size_t answerlen = 0;
|
|
@@ -109,172 +116,185 @@ int udp_server(int so)
|
|
|
char buf[sizeof(struct pdb_msg)];
|
|
|
int i;
|
|
|
|
|
|
- for (;;) {
|
|
|
+ for(;;) {
|
|
|
fromaddrlen = sizeof(fromaddr);
|
|
|
- bytes_received = recvfrom(so, buf, sizeof(struct pdb_msg), 0, &fromaddr, &fromaddrlen);
|
|
|
- if (bytes_received<0) {
|
|
|
- LERR("recvfrom() failed with errno=%d (%s)\n", errno, strerror(errno));
|
|
|
- if ((errno==EAGAIN)||(errno==EINTR)||(errno==EWOULDBLOCK)) continue;
|
|
|
+ bytes_received = recvfrom(
|
|
|
+ so, buf, sizeof(struct pdb_msg), 0, &fromaddr, &fromaddrlen);
|
|
|
+ if(bytes_received < 0) {
|
|
|
+ LERR("recvfrom() failed with errno=%d (%s)\n", errno,
|
|
|
+ strerror(errno));
|
|
|
+ if((errno == EAGAIN) || (errno == EINTR) || (errno == EWOULDBLOCK))
|
|
|
+ continue;
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- switch (buf[0]) {
|
|
|
- case PDB_VERSION_1:
|
|
|
- /* get received bytes */
|
|
|
- memcpy(&msg, buf, bytes_received);
|
|
|
-// pdb_msg_dbg(msg);
|
|
|
- short int *_id = (short int *)&(msg.hdr.id); /* make gcc happy */
|
|
|
- msg.hdr.id = ntohs(*_id);
|
|
|
-
|
|
|
- i = 0;
|
|
|
- while (i < strlen(msg.bdy.payload)) {
|
|
|
- if (msg.bdy.payload[i] < '0' || msg.bdy.payload[i] > '9') {
|
|
|
- pdb_msg_format_send(&msg, PDB_VERSION_1, PDB_TYPE_REPLY_ID, PDB_CODE_NOT_NUMBER, htons(msg.hdr.id), NULL, 0);
|
|
|
- goto msg_send;
|
|
|
- }
|
|
|
- i++;
|
|
|
- }
|
|
|
- /* lookup pdb_id */
|
|
|
- carrierid=lookup_number(msg.bdy.payload);
|
|
|
-
|
|
|
- /* check if not found pdb_id */
|
|
|
- if (carrierid == 0) {
|
|
|
- pdb_msg_format_send(&msg, PDB_VERSION_1, PDB_TYPE_REPLY_ID, PDB_CODE_NOT_FOUND, htons(msg.hdr.id), NULL, 0);
|
|
|
- goto msg_send;
|
|
|
- }
|
|
|
-
|
|
|
- /* convert to network byte order*/
|
|
|
- carrierid = htons(carrierid);
|
|
|
-
|
|
|
- /* prepare the message payload to be sent
|
|
|
+ switch(buf[0]) {
|
|
|
+ case PDB_VERSION_1:
|
|
|
+ /* get received bytes */
|
|
|
+ memcpy(&msg, buf, bytes_received);
|
|
|
+ // pdb_msg_dbg(msg);
|
|
|
+ short int *_id =
|
|
|
+ (short int *)&(msg.hdr.id); /* make gcc happy */
|
|
|
+ msg.hdr.id = ntohs(*_id);
|
|
|
+
|
|
|
+ i = 0;
|
|
|
+ while(i < strlen(msg.bdy.payload)) {
|
|
|
+ if(msg.bdy.payload[i] < '0' || msg.bdy.payload[i] > '9') {
|
|
|
+ pdb_msg_format_send(&msg, PDB_VERSION_1,
|
|
|
+ PDB_TYPE_REPLY_ID, PDB_CODE_NOT_NUMBER,
|
|
|
+ htons(msg.hdr.id), NULL, 0);
|
|
|
+ goto msg_send;
|
|
|
+ }
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ /* lookup pdb_id */
|
|
|
+ carrierid = lookup_number(msg.bdy.payload);
|
|
|
+
|
|
|
+ /* check if not found pdb_id */
|
|
|
+ if(carrierid == -1) {
|
|
|
+ pdb_msg_format_send(&msg, PDB_VERSION_1, PDB_TYPE_REPLY_ID,
|
|
|
+ PDB_CODE_NOT_FOUND, htons(msg.hdr.id), NULL, 0);
|
|
|
+ goto msg_send;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* convert to network byte order*/
|
|
|
+ carrierid = htons(carrierid);
|
|
|
+
|
|
|
+ /* prepare the message payload to be sent
|
|
|
* add the number string and append the carrier id
|
|
|
*/
|
|
|
- memcpy(buf, msg.bdy.payload, msg.hdr.length - sizeof(msg.hdr));
|
|
|
- memcpy(buf + msg.hdr.length - sizeof(msg.hdr), &carrierid, sizeof(carrierid));
|
|
|
-
|
|
|
- /* all ok, send pdb_msg with pdb_id in payload */
|
|
|
- pdb_msg_format_send(&msg, PDB_VERSION_1, PDB_TYPE_REPLY_ID, PDB_CODE_OK, htons(msg.hdr.id), buf, msg.hdr.length - sizeof(msg.hdr) + sizeof(carrierid));
|
|
|
- goto msg_send;
|
|
|
-
|
|
|
- break;
|
|
|
-
|
|
|
- /* old pdb version; no pdb_msg used */
|
|
|
- default:
|
|
|
- /* take only digits */
|
|
|
- i=0;
|
|
|
- while ((i<bytes_received) && (buf[i]>='0') && (buf[i]<='9')) i++;
|
|
|
- buf[i]=0; /* terminate string */
|
|
|
- i++;
|
|
|
-
|
|
|
- /* lookup pdb_id */
|
|
|
- carrierid=lookup_number(buf);
|
|
|
-
|
|
|
- /* convert to network byte order*/
|
|
|
- carrierid=htons(carrierid);
|
|
|
-
|
|
|
- /* append carrier id to answer */
|
|
|
- memcpy(&(buf[i]), &carrierid, sizeof(carrierid));
|
|
|
- answerlen=i+sizeof(carrierid);
|
|
|
- goto buf_send;
|
|
|
-
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
-msg_send:
|
|
|
-// pdb_msg_dbg(msg);
|
|
|
- if (pdb_msg_server_send(so, (char*)&msg, msg.hdr.length, &fromaddr, fromaddrlen) < 0) {
|
|
|
- return -1;
|
|
|
- }
|
|
|
- continue;
|
|
|
-
|
|
|
-buf_send:
|
|
|
- if (pdb_msg_server_send(so, buf, answerlen, &fromaddr, fromaddrlen)) {
|
|
|
- return -1;
|
|
|
- }
|
|
|
- continue;
|
|
|
- }
|
|
|
+ memcpy(buf, msg.bdy.payload, msg.hdr.length - sizeof(msg.hdr));
|
|
|
+ memcpy(buf + msg.hdr.length - sizeof(msg.hdr), &carrierid,
|
|
|
+ sizeof(carrierid));
|
|
|
+
|
|
|
+ /* all ok, send pdb_msg with pdb_id in payload */
|
|
|
+ pdb_msg_format_send(&msg, PDB_VERSION_1, PDB_TYPE_REPLY_ID,
|
|
|
+ PDB_CODE_OK, htons(msg.hdr.id), buf,
|
|
|
+ msg.hdr.length - sizeof(msg.hdr) + sizeof(carrierid));
|
|
|
+ goto msg_send;
|
|
|
+
|
|
|
+ break;
|
|
|
+
|
|
|
+ /* old pdb version; no pdb_msg used */
|
|
|
+ default:
|
|
|
+ /* take only digits */
|
|
|
+ i = 0;
|
|
|
+ while((i < bytes_received) && (buf[i] >= '0')
|
|
|
+ && (buf[i] <= '9'))
|
|
|
+ i++;
|
|
|
+ buf[i] = 0; /* terminate string */
|
|
|
+ i++;
|
|
|
+
|
|
|
+ /* lookup pdb_id */
|
|
|
+ carrierid = lookup_number(buf);
|
|
|
+
|
|
|
+ /* convert to network byte order*/
|
|
|
+ carrierid = htons(carrierid);
|
|
|
+
|
|
|
+ /* append carrier id to answer */
|
|
|
+ memcpy(&(buf[i]), &carrierid, sizeof(carrierid));
|
|
|
+ answerlen = i + sizeof(carrierid);
|
|
|
+ goto buf_send;
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- return -1;
|
|
|
-}
|
|
|
+ msg_send:
|
|
|
+ // pdb_msg_dbg(msg);
|
|
|
+ if(pdb_msg_server_send(
|
|
|
+ so, (char *)&msg, msg.hdr.length, &fromaddr, fromaddrlen)
|
|
|
+ < 0) {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ continue;
|
|
|
|
|
|
+ buf_send:
|
|
|
+ if(pdb_msg_server_send(so, buf, answerlen, &fromaddr, fromaddrlen)) {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
+ return -1;
|
|
|
+}
|
|
|
|
|
|
|
|
|
-int main(int argc, char *argv[]) {
|
|
|
+int main(int argc, char *argv[])
|
|
|
+{
|
|
|
int opt;
|
|
|
char *backend_data_filename = NULL;
|
|
|
char *bind_addr = DEFAULT_BINDADDR;
|
|
|
unsigned short bind_port = DEFAULT_PORT;
|
|
|
int use_syslog = 0;
|
|
|
- int log_level=LOG_WARNING;
|
|
|
+ int log_level = LOG_WARNING;
|
|
|
|
|
|
long int ret;
|
|
|
|
|
|
int so;
|
|
|
struct sockaddr_in sa;
|
|
|
|
|
|
- while ((opt = getopt(argc, argv, "m:i:p:vhdl:")) != -1) {
|
|
|
- switch (opt) {
|
|
|
- case 'm':
|
|
|
- backend_data_filename = optarg;
|
|
|
- break;
|
|
|
- case 'i':
|
|
|
- bind_addr=optarg;
|
|
|
- break;
|
|
|
- case 'p':
|
|
|
- ret=strtol(optarg, NULL, 10);
|
|
|
- if ((ret<0) || (ret>65535)) {
|
|
|
+ while((opt = getopt(argc, argv, "m:i:p:vhdl:")) != -1) {
|
|
|
+ switch(opt) {
|
|
|
+ case 'm':
|
|
|
+ backend_data_filename = optarg;
|
|
|
+ break;
|
|
|
+ case 'i':
|
|
|
+ bind_addr = optarg;
|
|
|
+ break;
|
|
|
+ case 'p':
|
|
|
+ ret = strtol(optarg, NULL, 10);
|
|
|
+ if((ret < 0) || (ret > 65535)) {
|
|
|
+ init_log("pdb_server", use_syslog);
|
|
|
+ LERR("invalid port '%s' specified.\n", optarg);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ bind_port = ret;
|
|
|
+ break;
|
|
|
+ case 'v':
|
|
|
+ set_log_level(LOG_INFO);
|
|
|
+ LINFO("version: pdb_server %d\n", PDB_VERSION);
|
|
|
+ return 0;
|
|
|
+ break;
|
|
|
+ case 'h':
|
|
|
init_log("pdb_server", use_syslog);
|
|
|
- LERR("invalid port '%s' specified.\n", optarg);
|
|
|
- return -1;
|
|
|
- }
|
|
|
- bind_port=ret;
|
|
|
- break;
|
|
|
- case 'v':
|
|
|
- set_log_level(LOG_INFO);
|
|
|
- LINFO("version: pdb_server %d\n", PDB_VERSION);
|
|
|
- return 0;
|
|
|
- break;
|
|
|
- case 'h':
|
|
|
- init_log("pdb_server", use_syslog);
|
|
|
- print_usage(argv[0]);
|
|
|
- return 0;
|
|
|
- break;
|
|
|
- case 'd':
|
|
|
- use_syslog=1;
|
|
|
- break;
|
|
|
- case 'l':
|
|
|
- ret=strtol(optarg, NULL, 10);
|
|
|
- if ((ret<LOG_EMERG-1) || (ret>LOG_DEBUG)) {
|
|
|
+ print_usage(argv[0]);
|
|
|
+ return 0;
|
|
|
+ break;
|
|
|
+ case 'd':
|
|
|
+ use_syslog = 1;
|
|
|
+ break;
|
|
|
+ case 'l':
|
|
|
+ ret = strtol(optarg, NULL, 10);
|
|
|
+ if((ret < LOG_EMERG - 1) || (ret > LOG_DEBUG)) {
|
|
|
+ init_log("pdb_server", use_syslog);
|
|
|
+ LERR("invalid log level '%s' specified.\n", optarg);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ log_level = ret;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
init_log("pdb_server", use_syslog);
|
|
|
- LERR("invalid log level '%s' specified.\n", optarg);
|
|
|
- return -1;
|
|
|
- }
|
|
|
- log_level=ret;
|
|
|
- break;
|
|
|
- default:
|
|
|
- init_log("pdb_server", use_syslog);
|
|
|
- LERR("invalid option '%c'.\n", opt);
|
|
|
- print_usage(argv[0]);
|
|
|
- return 1;
|
|
|
+ LERR("invalid option '%c'.\n", opt);
|
|
|
+ print_usage(argv[0]);
|
|
|
+ return 1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
init_log("pdb_server", use_syslog);
|
|
|
set_log_level(log_level);
|
|
|
|
|
|
- if (backend_data_filename==NULL) {
|
|
|
+ if(backend_data_filename == NULL) {
|
|
|
LERR("no data file specified.\n");
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
- if (init_backend(backend_data_filename)<0) {
|
|
|
+ if(init_backend(backend_data_filename) < 0) {
|
|
|
LERR("cannot initialize backend.\n");
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
so = socket(AF_INET, SOCK_DGRAM, 0);
|
|
|
- if (so<0) {
|
|
|
+ if(so < 0) {
|
|
|
LERR("socket() failed with errno=%d (%s)\n", errno, strerror(errno));
|
|
|
return -1;
|
|
|
}
|
|
@@ -282,13 +302,13 @@ int main(int argc, char *argv[]) {
|
|
|
memset(&sa, 0, sizeof(sa));
|
|
|
sa.sin_family = AF_INET;
|
|
|
sa.sin_port = htons(bind_port);
|
|
|
- if (inet_aton(bind_addr, &(sa.sin_addr))==0) {
|
|
|
+ if(inet_aton(bind_addr, &(sa.sin_addr)) == 0) {
|
|
|
LERR("invalid address '%s'.\n", bind_addr);
|
|
|
close(so);
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- if (bind(so, (struct sockaddr *) &sa, sizeof(sa))<0) {
|
|
|
+ if(bind(so, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
|
|
|
LERR("bind() failed with errno=%d (%s)\n", errno, strerror(errno));
|
|
|
close(so);
|
|
|
return -1;
|