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