nightmaremail

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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 }