00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 # include <ts/IpMap.h>
00027 # include <ts/IpMapConf.h>
00028 # include <ts/ink_memory.h>
00029 
00030 static size_t const ERR_STRING_LEN = 256;
00031 static size_t const MAX_LINE_SIZE = 2048;
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 int
00040 read_addr(char *line, int n, int *i, sockaddr* addr, char* err)
00041 {
00042   int k;
00043   char dst[INET6_ADDRSTRLEN];
00044   char* src = line + *i;
00045   bool bracketed_p = false;
00046 
00047   
00048   
00049   if ((*i < n) && ('[' == *src)) {
00050     ++*i, ++src, bracketed_p = true;
00051   }
00052 
00053   for (k = 0; k < INET6_ADDRSTRLEN && *i < n && (isxdigit(*src) || '.' == *src || ':' == *src) ; ++k, ++*i, ++src) {
00054     dst[k] = *src;
00055   }
00056 
00057   if (bracketed_p && (! (*i < n) || (']' != *src))) {
00058     snprintf(err, ERR_STRING_LEN, "Unclosed brackets");
00059     return EINVAL;
00060   }
00061 
00062   if (k == sizeof(dst)) {
00063     snprintf(err, ERR_STRING_LEN, "IP address too long");
00064     return EINVAL;
00065   }
00066 
00067   dst[k] = '\0';
00068   if (0 != ats_ip_pton(dst, addr)) {
00069     snprintf(err, ERR_STRING_LEN, "IP address '%s' improperly formatted", dst);
00070     return EINVAL;
00071   }
00072   return 0;
00073 }
00074 
00075 char *
00076 Load_IpMap_From_File(IpMap* map, int fd, const char *key_str)
00077 {
00078   char* zret = 0;
00079   FILE* f = fdopen(dup(fd), "r"); 
00080 
00081   if (f != NULL) {
00082     zret = Load_IpMap_From_File(map, f, key_str);
00083     fclose(f);
00084   } else {
00085     zret = (char *)ats_malloc(ERR_STRING_LEN);
00086     snprintf(zret, ERR_STRING_LEN, "Unable to reopen file descriptor as stream %d:%s", errno, strerror(errno));
00087   }
00088   return zret;
00089 }
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 static inline bool skip_space(char* line, int n, int& offset )
00098 {
00099   while (offset < n && isspace(line[offset]))
00100     ++offset;
00101   return offset < n;
00102 }
00103 
00104 
00105 char *
00106 Load_IpMap_From_File(IpMap* map, FILE* f, const char *key_str)
00107 {
00108   int i, n, line_no;
00109   int key_len = strlen(key_str);
00110   IpEndpoint laddr, raddr;
00111   char line[MAX_LINE_SIZE];
00112   char err_buff[ERR_STRING_LEN];
00113 
00114   
00115   map->mark(INADDR_LOOPBACK);
00116 
00117   line_no = 0;
00118   while (fgets(line, MAX_LINE_SIZE, f)) {
00119     ++line_no;
00120     n = strlen(line);
00121     
00122     for ( i = 0 ; i < n && ! isspace(line[i]); ++i)
00123       ;
00124     if (i != key_len || 0 != strncmp(line, key_str, key_len))
00125       continue;
00126     
00127     while (true) {
00128       if (!skip_space(line, n, i))
00129         break;
00130 
00131       if (0 != read_addr(line, n,  &i, &laddr.sa, err_buff)) {
00132         char *error_str = (char *)ats_malloc(ERR_STRING_LEN);
00133         snprintf(error_str, ERR_STRING_LEN, "Invalid input configuration (%s) at line %d offset %d - '%s'", err_buff,
00134                  line_no, i, line);
00135         return error_str;
00136       }
00137 
00138       if (!skip_space(line, n, i) || line[i] == ',') {
00139         
00140         map->mark(&laddr);
00141         if (i == n)
00142           break;
00143         else
00144           ++i;
00145       } else if (line[i] == '-') {
00146         
00147         
00148         ++i;
00149         if (!skip_space(line, n, i)) {
00150           char *error_str = (char *)ats_malloc(ERR_STRING_LEN);
00151           snprintf(error_str, ERR_STRING_LEN, "Invalid input (unterminated range) at line %d offset %d - '%s'", line_no,
00152                    i, line);
00153           return error_str;
00154         } else if (0 != read_addr(line, n, &i, &raddr.sa, err_buff)) {
00155           char *error_str = (char *)ats_malloc(ERR_STRING_LEN);
00156           snprintf(error_str, ERR_STRING_LEN, "Invalid input (%s) at line %d offset %d - '%s'", err_buff, line_no, i,
00157                    line);
00158           return error_str;
00159         }
00160         map->mark(&laddr.sa, &raddr.sa);
00161         if (!skip_space(line, n, i))
00162           break;
00163         if (line[i] != ',') {
00164           char *error_str = (char *)ats_malloc(ERR_STRING_LEN);
00165           snprintf(error_str, ERR_STRING_LEN, "Invalid input (expecting comma) at line %d offset %d - '%s'", line_no,
00166                    i, line);
00167           return error_str;
00168         }
00169         ++i;
00170       } else {
00171         char *error_str = (char *)ats_malloc(ERR_STRING_LEN);
00172         snprintf(error_str, ERR_STRING_LEN, "Invalid input (expecting dash or comma) at line %d offset %d", line_no, i);
00173         return error_str;
00174       }
00175     }
00176   }
00177   return 0;
00178 }