1 #include "msg_logger.h"
2 #include "exclusive_file.h"
3 
4 #include "AmUtils.h"
5 
6 #include <fcntl.h>
7 #include <netinet/in.h>
8 #include <arpa/inet.h>
9 
~file_msg_logger()10 file_msg_logger::~file_msg_logger()
11 {
12   exclusive_file::close(excl_fp);
13 }
14 
open(const char * filename)15 int file_msg_logger::open(const char* filename)
16 {
17   if(excl_fp) return 0;
18 
19   bool is_new = false;
20   if(exclusive_file::open(filename,excl_fp,is_new) < 0) {
21     return -1;
22   }
23 
24   if (is_new) {
25     write_file_header();
26 
27     // exclusive files are created locked
28     excl_fp->unlock();
29   }
30 
31   return 0;
32 }
33 
write(const void * buf,int len)34 int file_msg_logger::write(const void *buf, int len)
35 {
36   assert(excl_fp != NULL);
37   return excl_fp->write(buf,len);
38 }
39 
writev(const struct iovec * iov,int iovcnt)40 int file_msg_logger::writev(const struct iovec *iov, int iovcnt)
41 {
42   assert(excl_fp != NULL);
43   return excl_fp->writev(iov,iovcnt);
44 }
45 
46 //////////////////////////////////////////////////////////////////////////////////////
47 
addr2str(sockaddr_storage * addr)48 static string addr2str(sockaddr_storage* addr)
49 {
50   char ntop_buffer[INET6_ADDRSTRLEN];
51 
52   if(addr->ss_family == AF_INET) {
53     struct sockaddr_in *sin = (struct sockaddr_in *)addr;
54     if(!inet_ntop(AF_INET, &sin->sin_addr,
55 		  ntop_buffer,INET6_ADDRSTRLEN)) {
56       ERROR("Could not convert IPv4 address to string: %s",strerror(errno));
57       return "unknown";
58     }
59 
60     return string(ntop_buffer) + ":" + int2str(ntohs(sin->sin_port));
61   }
62 
63   struct sockaddr_in6* sin6 = (struct sockaddr_in6 *)addr;
64   if(!inet_ntop(AF_INET6, &sin6->sin6_addr,
65 		ntop_buffer,INET6_ADDRSTRLEN)) {
66     ERROR("Could not convert IPv6 address to string: %s",strerror(errno));
67     return "unknown";
68   }
69 
70   return string(ntop_buffer) + ":" + int2str(ntohs(sin6->sin6_port));
71 }
72 
73 #define WRITE_CSTSTR(str)                                           \
74   if(write(str,sizeof(str)-1) != sizeof(str)-1) {                   \
75     return -1;                                                      \
76   }
77 
78 #define WRITE_STLSTR(str)                                           \
79   if(write(str.c_str(),str.length()) != (ssize_t)str.length())  {   \
80     return -1;                                                      \
81   }
82 
83 
write_src_dst(const string & obj)84 int cf_msg_logger::write_src_dst(const string& obj)
85 {
86   if (known_destinations.find(obj) == known_destinations.end()) {
87     known_destinations.insert(obj);
88     WRITE_CSTSTR("<object name='");
89     WRITE_STLSTR(obj);
90     WRITE_CSTSTR("' desc='");
91     WRITE_STLSTR(obj);
92     WRITE_CSTSTR("'/>\n");
93   }
94 
95   return 0;
96 }
97 
log(const char * buf,int len,sockaddr_storage * src_ip,sockaddr_storage * dst_ip,cstring method,int reply_code)98 int cf_msg_logger::log(const char* buf, int len,
99 			 sockaddr_storage* src_ip,
100 			 sockaddr_storage* dst_ip,
101 			 cstring method, int reply_code)
102 {
103   assert(excl_fp != NULL);
104 
105   string src = addr2str(src_ip);
106   string dst = addr2str(dst_ip);
107 
108   AmLock _l(*(AmMutex*)excl_fp);
109 
110   write_src_dst(src);
111   write_src_dst(dst);
112 
113   string what = c2stlstr(method);
114   if(reply_code > 0) {
115     what = int2str(reply_code) + " / " + what;
116   }
117 
118   WRITE_CSTSTR("<call src='");
119   WRITE_STLSTR(src);
120   WRITE_CSTSTR("' dst='");
121   WRITE_STLSTR(dst);
122   WRITE_CSTSTR("' desc='");
123   WRITE_STLSTR(what);
124   WRITE_CSTSTR("'>\n");
125 
126   if(write(buf,len) != len) return -1;
127 
128   WRITE_CSTSTR("</call>\n");
129 
130   return 0;
131 }
132 
133