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 }