s/qmail 4.2.29a
Next generation secure email transport
Loading...
Searching...
No Matches
tcpto.c
Go to the documentation of this file.
1#include <sys/socket.h>
2#include <unistd.h>
3#include "tcpto.h"
4#include "open.h"
5#include "lock.h"
6#include "seek.h"
7#include "now.h"
8#include "ip.h"
9#include "ipalloc.h"
10#include "byte.h"
11#include "datetime.h"
12
13char tcpto_buf[1024];
14
15static int flagwasthere;
16static int fdlock;
17
18static int getbuf()
19{
20 int r;
21 int fd;
22
23 fdlock = open_write("queue/lock/tcpto");
24 if (fdlock == -1) return 0;
25 fd = open_read("queue/lock/tcpto");
26 if (fd == -1) { close(fdlock); return 0; }
27 if (lock_ex(fdlock) == -1) { close(fdlock); close(fd); return 0; }
28 r = read(fd,tcpto_buf,sizeof(tcpto_buf));
29 close(fd);
30 if (r < 0) { close(fdlock); return 0; }
31 r >>= 5;
32 if (!r) close(fdlock);
33 return r;
34}
35
36int tcpto(struct ip_mx *ix)
37{
38 int af = ix->af;
39 struct ip_address *ip = &ix->addr;
40 int n;
41 int i;
42 char *record;
43 datetime_sec when;
44
45 flagwasthere = 0;
46
47 n = getbuf();
48 if (!n) return 0;
49 close(fdlock);
50
51 record = tcpto_buf;
52
53 for (i = 0; i < n; ++i) {
54 if (af == record[0] && byte_equal(ip->d,af == AF_INET ? 4 : 16,record + 16)) {
55 flagwasthere = 1;
56 if (record[4] >= 2) {
57 when = (unsigned long) (unsigned char) record[11];
58 when = (when << 8) + (unsigned long) (unsigned char) record[10];
59 when = (when << 8) + (unsigned long) (unsigned char) record[9];
60 when = (when << 8) + (unsigned long) (unsigned char) record[8];
61
62 if (now() - when < ((60 + (getpid() & 31)) << 6)) return 1;
63 }
64 return 0;
65 }
66 record += 32;
67 }
68 return 0;
69}
70
71void tcpto_err(struct ip_mx *ix,int flagerr)
72{
73 int af = ix->af;
74 struct ip_address *ip = &ix->addr;
75 int n;
76 int i;
77 char *record;
78 datetime_sec when;
79 datetime_sec firstwhen;
80 int firstpos;
81 datetime_sec lastwhen;
82
83 if (!flagerr)
84 if (!flagwasthere)
85 return; /* could have been added, but not worth the effort to check */
86
87 n = getbuf();
88 if (!n) return;
89
90 record = tcpto_buf;
91
92 for (i = 0; i < n; ++i) {
93 if (af == record[0] && byte_equal(ip->d,af == AF_INET ? 4 : 16,record + 16)) {
94 if (!flagerr)
95 record[4] = 0;
96 else {
97 lastwhen = (unsigned long) (unsigned char) record[11];
98 lastwhen = (lastwhen << 8) + (unsigned long) (unsigned char) record[10];
99 lastwhen = (lastwhen << 8) + (unsigned long) (unsigned char) record[9];
100 lastwhen = (lastwhen << 8) + (unsigned long) (unsigned char) record[8];
101 when = now();
102
103 if (record[4] && (when < 120 + lastwhen)) { close(fdlock); return; }
104
105 if (++record[4] > 10) record[4] = 10;
106 record[8] = when; when >>= 8;
107 record[9] = when; when >>= 8;
108 record[10] = when; when >>= 8;
109 record[11] = when;
110 }
111 if (seek_set(fdlock,i << 5) == 0)
112 if (write(fdlock,record,32) < 32)
113 ; /*XXX*/
114 close(fdlock);
115 return;
116 }
117 record += 32;
118 }
119
120 if (!flagerr) { close(fdlock); return; }
121
122 record = tcpto_buf;
123
124 for (i = 0; i < n; ++i) {
125 if (!record[4]) break;
126 record += 32;
127 }
128
129 if (i >= n) {
130 firstpos = -1;
131 record = tcpto_buf;
132
133 for (i = 0; i < n; ++i) {
134 when = (unsigned long) (unsigned char) record[11];
135 when = (when << 8) + (unsigned long) (unsigned char) record[10];
136 when = (when << 8) + (unsigned long) (unsigned char) record[9];
137 when = (when << 8) + (unsigned long) (unsigned char) record[8];
138 when += (record[4] << 10);
139 if ((firstpos < 0) || (when < firstwhen)) {
140 firstpos = i;
141 firstwhen = when;
142 }
143 record += 32;
144 }
145 i = firstpos;
146 }
147
148 if (i >= 0) {
149 record = tcpto_buf + (i << 5);
150 record[0] = af;
151 if (af == AF_INET6)
152 byte_copy(record + 16,16,ip->d);
153 else {
154 byte_copy(record + 16,4,ip->d);
155 byte_copy(record + 20,12,"............");
156 }
157 when = now();
158 record[8] = when; when >>= 8;
159 record[9] = when; when >>= 8;
160 record[10] = when; when >>= 8;
161 record[11] = when;
162 record[4] = 1;
163 if (seek_set(fdlock,i << 5) == 0)
164 if (write(fdlock,record,32) < 32)
165 ; /*XXX*/
166 }
167
168 close(fdlock);
169}
long datetime_sec
Definition: datetime.h:15
datetime_sec now()
Definition: now.c:5
int fd
int getbuf()
Definition: qmail-qmqpd.c:103
Definition: ipalloc.h:8
union ip_mx::@0 addr
unsigned short af
Definition: ipalloc.h:9
char tcpto_buf[1024]
Definition: tcpto.c:13
void tcpto_err()
int tcpto()
void write()