tcpto.c (5275B)
1 #include "tcpto.h" 2 3 #include "open.h" 4 #include "lock.h" 5 #include "seek.h" 6 #include "now.h" 7 #include "ip.h" 8 #include "byte.h" 9 #include "datetime.h" 10 #include "readwrite.h" 11 12 char tcpto_buf[2048]; 13 14 static int flagwasthere; 15 static int fdlock; 16 17 static int 18 getbuf() 19 { 20 int r; 21 int fd; 22 23 fdlock = open_write("queue/lock/tcpto"); 24 if (fdlock == -1) 25 return 0; 26 fd = open_read("queue/lock/tcpto"); 27 if (fd == -1) { 28 close(fdlock); 29 return 0; 30 } 31 if (lock_ex(fdlock) == -1) { 32 close(fdlock); 33 close(fd); 34 return 0; 35 } 36 r = read(fd, tcpto_buf, sizeof(tcpto_buf)); 37 close(fd); 38 if (r == -1) { 39 close(fdlock); 40 return 0; 41 } 42 r >>= 5; 43 if (!r) 44 close(fdlock); 45 return r; 46 } 47 48 int 49 tcpto(struct ip_address *ip) 50 { 51 int n; 52 int i; 53 char *record; 54 55 flagwasthere = 0; 56 57 n = getbuf(); 58 if (!n) 59 return 0; 60 close(fdlock); 61 62 record = tcpto_buf; 63 for (i = 0; i < n; ++i) { 64 if (ip->is6) { 65 if (byte_equal(ip->ip.aaaa.d, 16, record)) { 66 flagwasthere = 1; 67 if (record[16] >= 2) { 68 datetime_sec when = (unsigned long)(unsigned char)record[11]; 69 when = (when << 8) + (unsigned long)(unsigned char)record[10]; 70 when = (when << 8) + (unsigned long)(unsigned char)record[9]; 71 when = (when << 8) + (unsigned long)(unsigned char)record[8]; 72 73 if (now() - when < ((60 + (getpid() & 31)) << 6)) 74 return 1; 75 } 76 return 0; 77 } 78 } else { 79 if (byte_equal("\0\0\0\0\0\0\0\0\0\0\0", 12, record)) 80 if (byte_equal(ip->ip.a.d, 4, record + 12)) { 81 flagwasthere = 1; 82 if (record[16] >= 2) { 83 datetime_sec when = (unsigned long)(unsigned char)record[11]; 84 when = (when << 8) + (unsigned long)(unsigned char)record[10]; 85 when = (when << 8) + (unsigned long)(unsigned char)record[9]; 86 when = (when << 8) + (unsigned long)(unsigned char)record[8]; 87 88 if (now() - when < ((60 + (getpid() & 31)) << 6)) 89 return 1; 90 } 91 return 0; 92 } 93 } 94 record += 12 + 16; // was 16, now 12 + inet6 95 } 96 return 0; 97 } 98 99 void 100 tcpto_err(struct ip_address *ip, int flagerr) 101 { 102 int n; 103 int i; 104 char *record; 105 datetime_sec when; 106 datetime_sec lastwhen; 107 108 if (!flagerr) 109 if (!flagwasthere) 110 return; /* could have been added, but not worth the effort to check */ 111 112 n = getbuf(); 113 if (!n) 114 return; 115 116 record = tcpto_buf; 117 for (i = 0; i < n; ++i) { 118 if (ip->is6) { 119 if (byte_equal(ip->ip.aaaa.d, 16, record)) { 120 if (!flagerr) 121 record[16] = 0; 122 else { 123 lastwhen = (unsigned long)(unsigned char)record[23]; 124 lastwhen = (lastwhen << 8) + (unsigned long)(unsigned char)record[22]; 125 lastwhen = (lastwhen << 8) + (unsigned long)(unsigned char)record[21]; 126 lastwhen = (lastwhen << 8) + (unsigned long)(unsigned char)record[20]; 127 when = now(); 128 129 if (record[16] && (when < 120 + lastwhen)) { 130 close(fdlock); 131 return; 132 } 133 134 if (++record[16] > 10) 135 record[16] = 10; 136 record[20] = when; 137 when >>= 8; 138 record[21] = when; 139 when >>= 8; 140 record[22] = when; 141 when >>= 8; 142 record[23] = when; 143 } 144 if (seek_set(fdlock, i << 4) == 0) 145 if (write(fdlock, record, 16) < 16) 146 ; /* XXX */ 147 close(fdlock); 148 return; 149 } 150 } else { 151 if (byte_equal("\0\0\0\0""\0\0\0\0""\0\0\0", 12, record)) 152 if (byte_equal(ip->ip.a.d, 4, record + 12)) { 153 if (!flagerr) 154 record[16] = 0; 155 else { 156 lastwhen = (unsigned long)(unsigned char)record[23]; 157 lastwhen = (lastwhen << 8) + (unsigned long)(unsigned char)record[22]; 158 lastwhen = (lastwhen << 8) + (unsigned long)(unsigned char)record[21]; 159 lastwhen = (lastwhen << 8) + (unsigned long)(unsigned char)record[20]; 160 when = now(); 161 162 if (record[16] && (when < 120 + lastwhen)) { 163 close(fdlock); 164 return; 165 } 166 167 if (++record[16] > 10) 168 record[16] = 10; 169 record[20] = when; 170 when >>= 8; 171 record[21] = when; 172 when >>= 8; 173 record[22] = when; 174 when >>= 8; 175 record[23] = when; 176 } 177 if (seek_set(fdlock, i << 4) == 0) 178 if (write(fdlock, record, 16) < 16) 179 ; /* XXX */ 180 close(fdlock); 181 return; 182 } 183 } 184 record += 12 + 16; 185 } 186 187 if (!flagerr) { 188 close(fdlock); 189 return; 190 } 191 192 record = tcpto_buf; 193 for (i = 0; i < n; ++i) { 194 if (!record[16]) 195 break; 196 record += 12 + 16; 197 } 198 199 if (i >= n) { 200 int firstpos = -1; 201 datetime_sec firstwhen; 202 record = tcpto_buf; 203 for (i = 0; i < n; ++i) { 204 when = (unsigned long)(unsigned char)record[23]; 205 when = (when << 8) + (unsigned long)(unsigned char)record[22]; 206 when = (when << 8) + (unsigned long)(unsigned char)record[21]; 207 when = (when << 8) + (unsigned long)(unsigned char)record[20]; 208 when += (record[16] << 10); 209 if ((firstpos < 0) || (when < firstwhen)) { 210 firstpos = i; 211 firstwhen = when; 212 } 213 record += 12 + 16; 214 } 215 i = firstpos; 216 } 217 218 if (i >= 0) { 219 record = tcpto_buf + (i << 5); 220 if (ip->is6) { 221 byte_copy(record, 16, ip->ip.aaaa.d); 222 } else { 223 byte_copy(record, 12, "\0\0\0\0""\0\0\0\0""\0\0\0"); 224 byte_copy(record + 12, 4, ip->ip.a.d); 225 } 226 when = now(); 227 record[20] = when; 228 when >>= 8; 229 record[21] = when; 230 when >>= 8; 231 record[22] = when; 232 when >>= 8; 233 record[23] = when; 234 record[16] = 1; 235 if (seek_set(fdlock, i << 5) == 0) 236 if (write(fdlock, record, 12 + 16) < (12 + 16)) 237 ; /* XXX */ 238 } 239 240 close(fdlock); 241 }