|
|
|
|
@ -53,21 +53,6 @@
|
|
|
|
|
|
|
|
|
|
#include <fstream>
|
|
|
|
|
|
|
|
|
|
#ifndef UNIX_PATH_MAX
|
|
|
|
|
#define UNIX_PATH_MAX 104
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// timeout in us (ms/1000)
|
|
|
|
|
#define SER_WRITE_TIMEOUT 250000 // 250 ms
|
|
|
|
|
// write retry interval in us
|
|
|
|
|
#define SER_WRITE_INTERVAL 50000 // 50 ms
|
|
|
|
|
|
|
|
|
|
// timeout in us (ms/1000)
|
|
|
|
|
#define SER_SIPREQ_TIMEOUT 5*60*1000*1000 // 5 minutes
|
|
|
|
|
#define SER_DBREQ_TIMEOUT 250000 // 250 ms
|
|
|
|
|
// read retry interval in us
|
|
|
|
|
#define SER_READ_INTERVAL 50000 // 50 ms
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static char _int2str_lookup[] = { '0', '1', '2', '3', '4', '5', '6' , '7', '8', '9' };
|
|
|
|
|
|
|
|
|
|
@ -433,142 +418,6 @@ int parse_return_code(const char* lbuf, unsigned int& res_code, string& res_msg
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int fifo_get_line(FILE* fifo_stream, char* str, size_t len)
|
|
|
|
|
{
|
|
|
|
|
char c;
|
|
|
|
|
size_t l;
|
|
|
|
|
char* s=str;
|
|
|
|
|
|
|
|
|
|
if(!len)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
l=len;
|
|
|
|
|
|
|
|
|
|
while( l && (c=fgetc(fifo_stream)) && !ferror(fifo_stream) && c!=EOF && c!='\n' ){
|
|
|
|
|
if(c!='\r'){
|
|
|
|
|
*(s++) = c;
|
|
|
|
|
l--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(l>0){
|
|
|
|
|
// We need one more character
|
|
|
|
|
// for trailing '\0'.
|
|
|
|
|
*s='\0';
|
|
|
|
|
|
|
|
|
|
return int(s-str);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
// buffer overran.
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int fifo_get_lines(FILE* fifo_stream, char* str, size_t len)
|
|
|
|
|
{
|
|
|
|
|
int l=0,max=len;
|
|
|
|
|
char* s=str;
|
|
|
|
|
|
|
|
|
|
if(!len)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
while( max>0 && (l=fifo_get_line(fifo_stream,s,max)) && l!=-1 ) {
|
|
|
|
|
if(!strcmp(".",s))
|
|
|
|
|
break;
|
|
|
|
|
s+=l;
|
|
|
|
|
*(s++)='\n';
|
|
|
|
|
max-=l+1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s[0]='\0';
|
|
|
|
|
|
|
|
|
|
return (l!=-1 ? s-str : -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int fifo_get_param(FILE* fp, string& p, char* line_buf, unsigned int size)
|
|
|
|
|
{
|
|
|
|
|
if( fifo_get_line(fp,line_buf,size) !=-1 ){
|
|
|
|
|
if(!strcmp(".",line_buf))
|
|
|
|
|
line_buf[0]='\0';
|
|
|
|
|
|
|
|
|
|
p = line_buf;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
ERROR("could not read from FIFO: %s\n",strerror(errno));
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int msg_get_line(char*& msg_c, char* str, size_t len)
|
|
|
|
|
{
|
|
|
|
|
size_t l;
|
|
|
|
|
char* s=str;
|
|
|
|
|
|
|
|
|
|
if(!len)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
for(l=len; l && (*msg_c) && (*msg_c !='\n'); msg_c++ ){
|
|
|
|
|
*(s++) = *msg_c;
|
|
|
|
|
l--;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(*msg_c)
|
|
|
|
|
msg_c++;
|
|
|
|
|
|
|
|
|
|
if(l>0){
|
|
|
|
|
// We need one more character
|
|
|
|
|
// for trailing '\0'.
|
|
|
|
|
*s='\0';
|
|
|
|
|
|
|
|
|
|
return int(s-str);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
ERROR("buffer too small (size=%u)\n",(unsigned int)len);
|
|
|
|
|
// buffer overran.
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int msg_get_lines(char*& msg_c, char* str, size_t len)
|
|
|
|
|
{
|
|
|
|
|
int l=0,max=len;
|
|
|
|
|
char* s=str;
|
|
|
|
|
|
|
|
|
|
if(!len)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
while( max>0 && (l=msg_get_line(msg_c,s,max)) && l!=-1 ) {
|
|
|
|
|
if(!strcmp(".",s) || !strcmp("\r",s))
|
|
|
|
|
break;
|
|
|
|
|
s+=l;
|
|
|
|
|
*(s++)='\n';
|
|
|
|
|
max-=l+1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s[0]='\0';
|
|
|
|
|
|
|
|
|
|
return (l!=-1 ? s-str : -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int msg_get_param(char*& msg_c, string& p, char* line_buf, unsigned int size)
|
|
|
|
|
{
|
|
|
|
|
if( msg_get_line(msg_c,line_buf,size) != -1 ){
|
|
|
|
|
|
|
|
|
|
if(!strcmp(".",line_buf))
|
|
|
|
|
line_buf[0]='\0';
|
|
|
|
|
|
|
|
|
|
p = line_buf;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
ERROR("msg_get_line failed\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool file_exists(const string& name)
|
|
|
|
|
{
|
|
|
|
|
FILE* test_fp = fopen(name.c_str(),"r");
|
|
|
|
|
@ -589,87 +438,12 @@ string filename_from_fullpath(const string& path)
|
|
|
|
|
|
|
|
|
|
string get_addr_str(struct in_addr in)
|
|
|
|
|
{
|
|
|
|
|
char res[46]; // INET6_ADDRSTRLEN
|
|
|
|
|
if (inet_ntop(AF_INET, &in, res, 46))
|
|
|
|
|
char res[INET_ADDRSTRLEN];
|
|
|
|
|
if (inet_ntop(AF_INET, &in, res, INET_ADDRSTRLEN))
|
|
|
|
|
return string(res);
|
|
|
|
|
else return "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AmMutex inet_gethostbyname;
|
|
|
|
|
string get_ip_from_name(const string& name)
|
|
|
|
|
{
|
|
|
|
|
inet_gethostbyname.lock();
|
|
|
|
|
struct hostent *he = gethostbyname(name.c_str());
|
|
|
|
|
if(!he){
|
|
|
|
|
inet_gethostbyname.unlock();
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
struct in_addr a;
|
|
|
|
|
bcopy(he->h_addr, (char *) &a, sizeof(a));
|
|
|
|
|
inet_gethostbyname.unlock();
|
|
|
|
|
return get_addr_str(a);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Takes a string representation of an IP address, or an FQDN,
|
|
|
|
|
* and populates the provided struct sockaddr_in (similar to
|
|
|
|
|
* inet_aton).
|
|
|
|
|
* Returns the hostent for the input, or NULL on failure.
|
|
|
|
|
* Almost certainly won't work with IPv6 addresses.
|
|
|
|
|
*/
|
|
|
|
|
int populate_sockaddr_in_from_name(const string& name, struct sockaddr_in *sa) {
|
|
|
|
|
|
|
|
|
|
if (NULL == sa) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int res = 0;
|
|
|
|
|
struct addrinfo hints;
|
|
|
|
|
struct addrinfo *result, *rp;
|
|
|
|
|
memset(&hints, 0, sizeof(struct addrinfo));
|
|
|
|
|
hints.ai_family = AF_INET; // AF_UNSPEC for IPv4 or IPv6
|
|
|
|
|
hints.ai_socktype = SOCK_DGRAM; // Datagram socket.
|
|
|
|
|
hints.ai_flags = AI_ADDRCONFIG;
|
|
|
|
|
hints.ai_protocol = 0; // Any protocol.
|
|
|
|
|
|
|
|
|
|
int s = getaddrinfo(name.c_str(), NULL, &hints, &result);
|
|
|
|
|
if (s != 0) {
|
|
|
|
|
WARN("getaddrinfo failed on %s: %s.\n",
|
|
|
|
|
name.c_str(),
|
|
|
|
|
gai_strerror(s));
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (rp = result; rp != NULL; rp = rp->ai_next) {
|
|
|
|
|
if ((rp->ai_addrlen != sizeof(struct sockaddr_in)) || // Should not happen.
|
|
|
|
|
(rp->ai_socktype != SOCK_DGRAM) ||
|
|
|
|
|
(rp->ai_family != AF_INET)) // TODO: Won't behave with IPv6.
|
|
|
|
|
continue;
|
|
|
|
|
memcpy(&(sa->sin_addr),
|
|
|
|
|
&((struct sockaddr_in *)rp->ai_addr)->sin_addr,
|
|
|
|
|
sizeof(sa->sin_addr));
|
|
|
|
|
res = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
freeaddrinfo(result);
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string uri_from_name_addr(const string& name_addr)
|
|
|
|
|
{
|
|
|
|
|
string uri = name_addr;
|
|
|
|
|
string::size_type pos = uri.find('<');
|
|
|
|
|
|
|
|
|
|
if(pos != string::npos)
|
|
|
|
|
uri.erase(0,pos+1);
|
|
|
|
|
|
|
|
|
|
pos = uri.find('>');
|
|
|
|
|
if(pos != string::npos)
|
|
|
|
|
uri.erase(pos,uri.length()-pos);
|
|
|
|
|
|
|
|
|
|
return uri;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef SUPPORT_IPV6
|
|
|
|
|
#include <netdb.h>
|
|
|
|
|
|
|
|
|
|
@ -766,88 +540,6 @@ string add2path( const string& path, int n_suffix, ...)
|
|
|
|
|
return outpath;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int write_to_fifo(const string& fifo, const char * buf, unsigned int len)
|
|
|
|
|
{
|
|
|
|
|
int fd_fifo;
|
|
|
|
|
int retry = SER_WRITE_TIMEOUT / SER_WRITE_INTERVAL;
|
|
|
|
|
|
|
|
|
|
for(;retry>0; retry--){
|
|
|
|
|
|
|
|
|
|
if((fd_fifo = open(fifo.c_str(),
|
|
|
|
|
O_WRONLY | O_NONBLOCK)) == -1) {
|
|
|
|
|
ERROR("while opening %s: %s\n",
|
|
|
|
|
fifo.c_str(),strerror(errno));
|
|
|
|
|
|
|
|
|
|
if(retry)
|
|
|
|
|
sleep_us(50000);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!retry)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
DBG("write_to_fifo: <%s>\n",buf);
|
|
|
|
|
int l = write(fd_fifo,buf,len);
|
|
|
|
|
close(fd_fifo);
|
|
|
|
|
|
|
|
|
|
if(l==-1)
|
|
|
|
|
ERROR("while writing: %s\n",strerror(errno));
|
|
|
|
|
else
|
|
|
|
|
DBG("Write to fifo: completed\n");
|
|
|
|
|
|
|
|
|
|
return l;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int write_to_socket(int sd, const char* to_addr, const char * buf, unsigned int len)
|
|
|
|
|
{
|
|
|
|
|
int retry = SER_WRITE_TIMEOUT / SER_WRITE_INTERVAL;
|
|
|
|
|
int ret=-1;
|
|
|
|
|
|
|
|
|
|
struct sockaddr_un ser_addr;
|
|
|
|
|
memset (&ser_addr, 0, sizeof (ser_addr));
|
|
|
|
|
ser_addr.sun_family = AF_UNIX;
|
|
|
|
|
strncpy(ser_addr.sun_path,to_addr,UNIX_PATH_MAX);
|
|
|
|
|
|
|
|
|
|
DBG("sending: <%.*s>\n",len,buf);
|
|
|
|
|
|
|
|
|
|
for(;retry>0;retry--){
|
|
|
|
|
|
|
|
|
|
if( (sendto(sd,buf,len,MSG_DONTWAIT,
|
|
|
|
|
(struct sockaddr*)&ser_addr,
|
|
|
|
|
sizeof(struct sockaddr_un)) == -1) ) {
|
|
|
|
|
|
|
|
|
|
if(errno == EAGAIN){
|
|
|
|
|
if(retry)
|
|
|
|
|
sleep_us(SER_WRITE_INTERVAL);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ERROR("while sending request to %s: %s\n",
|
|
|
|
|
ser_addr.sun_path,strerror(errno));
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!retry){
|
|
|
|
|
ERROR("timeout while sending request to %s\n",ser_addr.sun_path);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DBG("write to unix socket: completed\n");
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
|
|
error:
|
|
|
|
|
// close(sd);
|
|
|
|
|
// return (ret == -1 ? ret : len);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int get_local_addr_for_dest(sockaddr_storage* remote_ip, sockaddr_storage* local)
|
|
|
|
|
{
|
|
|
|
|
int temp_sock = socket(remote_ip->ss_family, SOCK_DGRAM, 0 );
|
|
|
|
|
|