1
<!-- Automagically generated by the ToDo program on Thu Jun 23 13:18:43 2005 -->
2
<todo version="0.1.18">
3
    <title>
4
        Postmaster
5
    </title>
6
    <note priority="veryhigh" time="1099264722" done="1099303821">
7
        figure out why mailid is assigned twice for mail from:&lt;&gt;
8
        <comment>
9
            fixed bug in impatient
10
        </comment>
11
    </note>
12
    <note priority="veryhigh" time="1107927331" done="1107978554">
13
        read timeouts currently are behind 'safe'
14
        <comment>
15
            fixed
16
        </comment>
17
    </note>
18
    <note priority="veryhigh" time="1108001576" done="1108047273">
19
        process crashes when spool file is erased
20
        <comment>
21
            fixed
22
        </comment>
23
    </note>
24
    <note priority="veryhigh" time="1108043262" done="1108047347">
25
        What SessionState are we in when StartData fails?
26
        <comment>
27
            handleDialog will set HaveHelo
28
        </comment>
29
    </note>
30
    <note priority="high" time="1098655722" done="1098737399">
31
        Handler needs a Handler(Status|State) field in Target.
32
        <comment>
33
            Implemented. We know have 5 handler status
34
            codes: Ready, Live, Succeeded, Failed,
35
            FailedPermanently. The Deliver event uses them
36
            to determine correct SmtpReply. The semantics
37
            are: If one target is okay, the whole data
38
            transaction is okay. If all fail permanently,
39
            the transaction fails permanently. Otherwise the
40
            transaction falis with a 4xx code.
41
        </comment>
42
    </note>
43
    <note priority="high" time="1098656254" done="1107927357">
44
        We need a spooler.
45
46
        If the external handler returns an error, we cannot
47
        create a bounce message because we don't have the
48
        payload anymore! With sendmail as backend, this
49
        doesn't matter because sendmail does bounce the mail
50
        in case of an error, but we rather soon need a
51
        spooler that writes everything to disk, just in
52
        case. From there, a spool manager could retry
53
        delivery, etc.
54
        <comment>
55
            done
56
        </comment>
57
    </note>
58
    <note priority="high" time="1098658162" done="1099014967">
59
        Need combinators to create targets (fwd, alias, etc.)
60
        <comment>
61
            done: 'relay' and 'pipe'
62
        </comment>
63
    </note>
64
    <note priority="high" time="1098924318" done="1107739248">
65
        smtpdMain has to protect accept with 'bracket'
66
        <comment>
67
            accept looks safe now for all practical purposes
68
        </comment>
69
    </note>
70
    <note priority="high" time="1099253001" done="1107978575">
71
        Start shells with "set +e".
72
        <comment>
73
            we don't start shells anymore
74
        </comment>
75
    </note>
76
    <note priority="high" time="1099253334" done="1107534743">
77
        Replace Val with Data.Dynamic
78
        <comment>
79
            code moved to MonadEnv module
80
        </comment>
81
    </note>
82
    <note priority="high" time="1099253516" done="1107739100">
83
        Model a generic stream processor through a Stream a datatype!
84
        <comment>
85
            Unnecessary with the new design.
86
        </comment>
87
    </note>
88
    <note priority="medium" time="1098325598" done="1098585670">
89
        Does the eventHandler have to set sessionState?
90
        <comment>
91
            No, it does not. handleDialog and handleData set
92
            the sessionState according to the results of
93
            smtpdFSM. The user callbacks should not (and in
94
            fact cannot) interfere.
95
        </comment>
96
    </note>
97
    <note priority="medium" time="1098329354" done="1107739271">
98
        Log timeouts where they occur, not in runSmtpd.
99
        <comment>
100
            Nope, we use safeWrite combinator now.
101
        </comment>
102
    </note>
103
    <note priority="medium" time="1098329496" done="1098585655">
104
        Add "Greeting" event.
105
        <comment>
106
            Done. The event is triggered by runSmtpd before
107
            anything else happens. It can be used to
108
            initialize the SmtpdState for the rest of the
109
            session.
110
        </comment>
111
    </note>
112
    <note priority="medium" time="1098713602" done="1098738894">
113
        If "greeting" returns failure code, abort the connection.
114
        <comment>
115
            Implemented. Anything but 2xx will cause
116
            runSmtpd to drop the connection.
117
        </comment>
118
    </note>
119
    <note priority="medium" time="1098748188" done="1107978651">
120
        Avoid zombie processes by waiting for the child
121
122
        The changes in commitTarget (safeGetExitCode instead
123
        of waitForProcess) should fix that.
124
125
        There remains the case of the process aborting
126
        abnormally, or the I/O thread that holds the handle
127
        received an exception. I have a finalizer attached
128
        to the ExternHandle, which will kill, then wait for
129
        the child. Will see whether that helps.
130
        <comment>
131
            fixed in new architecture
132
        </comment>
133
    </note>
134
    <note priority="medium" time="1098894546" done="1107927427">
135
        'smtpdMain' should expect a Socket, not a PortID.
136
        <comment>
137
            smtpdServer can run from any socket now
138
        </comment>
139
    </note>
140
    <note priority="medium" time="1098939046" done="1099015643">
141
        I need a better shutdown mechanism than fail
142
        <comment>
143
            done: reply 221 and 421 will drop the connection
144
        </comment>
145
    </note>
146
    <note priority="medium" time="1098944687" done="1107927451">
147
        need debugEH-like wrapper to dump the environment
148
        <comment>
149
            isn't trivially possible with Env anymory
150
        </comment>
151
    </note>
152
    <note priority="medium" time="1099011048" done="1107927633">
153
        Need CRLF conversion for local mailers.
154
155
        I have to convert CRLF to LF because some programs,
156
        like procmail, don't understand CRLF-ended lines.
157
        This is a job for the dataHandler, obviously. I just
158
        wonder how to trigger it! For every pipe? Just for
159
        procmail? Or do nothing and have people call
160
161
          #! /bin/sh --
162
          sed -e 's/^M$//' | /usr/bin/procmail $*
163
164
        instead? I need a more flexible Target type. There's
165
        no way around it. Ideally, a Target could be written
166
        completely outside of Postmaster, then this were the
167
        user's problem and not mine. That's the way to do
168
        it.
169
        <comment>
170
            no more local mailers
171
        </comment>
172
    </note>
173
    <note priority="medium" time="1099013220" done="1099093120">
174
        Need 'closeTarget' to run before 'commitTarget'.
175
        <comment>
176
            implemented
177
        </comment>
178
    </note>
179
    <note priority="medium" time="1099252968" done="1107739350">
180
        write ts :: EnvT a -&gt; EnvT (Timestamped a)
181
        <comment>
182
            Not possible because EnvT is not bound to one variable.
183
        </comment>
184
    </note>
185
    <note priority="medium" time="1107470824" done="1107534805">
186
        replace error with fail wherever possible
187
        <comment>
188
            done
189
        </comment>
190
    </note>
191
    <note priority="medium" time="1107743614" done="1107978607">
192
        smtpd has to check SessionState between lines!
193
        <comment>
194
            No, according to the RFC our pipelining is fine.
195
        </comment>
196
    </note>
197
    <note priority="medium" time="1108001616" done="1108052981">
198
        don't export feed and other internals in FSM.*
199
        <comment>
200
            Well, let's expert feed. Whatever.
201
        </comment>
202
    </note>
203
    <note priority="low" time="1098627718" done="1107927500">
204
        Do "performGC &gt;&gt; yield" when resources run out.
205
206
        Although a Handle is garbage-collected in Haskell,
207
        it is not clear when the appropriate finalizer will
208
        be run! Thus, it might be a good idea to trigger an
209
        explicit garbage collection in case we've received
210
        an exception which signifies that system resources
211
        are unavailable. This applies to all kind of
212
        finalizer-based resource management. The only case
213
        in which the RTS will run the GC itself is when
214
        memory runs out. But other resources (file
215
        descriptors, etc.) don't do that.
216
        <comment>
217
            we don't use finalizers anymore
218
        </comment>
219
    </note>
220
    <note priority="low" time="1098732401" done="1107739182">
221
        Need a sub-monad class.
222
223
        I need a class which handles the case where the
224
        state of the outer monad contains the state of the
225
        inner monad. The class would contain glue code
226
        telling me how to get/put the state into the outer
227
        monads data type, and then a simple 'run' should
228
        suffice to call all sub-monads.
229
230
        Declaring "MonadState st" for every contained state
231
        might do the trick, but I need to allow undecidable
232
        instances to do that.
233
234
          instance (MonadState Config m)
235
            =&gt; MonadReader Callbacks m where
236
        <comment>
237
            New design made this unnecessary.
238
        </comment>
239
    </note>
240
    <note priority="low" time="1098754939" done="1107978635">
241
        waitForProcess throws exceptions I have to catch
242
243
        Glynn Clements writes:
244
245
        &gt; Both [getProcessExitCode and waitForProcess]
246
        &gt; will throw an exception if the process
247
        &gt; terminated on a signal.
248
249
        I've fixed it now, I think. It is horrible:
250
        'safeWaitForProcess' basically busy-polls the status
251
        every 1/10 second with a 'timeout' and 'catch'
252
        wrapped around the whole computation. Processes that
253
        are terminated by signals will be mapped to "exit 1".
254
255
        It appears to be robust so far.
256
        <comment>
257
            The entire 'extern' stuff is gone.
258
        </comment>
259
    </note>
260
    <note priority="low" time="1099006932" done="1107927587">
261
        Batch procmail calls.
262
263
        Procmail's -d option allows more than one recipient.
264
        I need to support that in a useful way, but the
265
        current Target definition doesn't allow me to batch
266
        it, because -- in the general case -- I cannot batch
267
        pipe.
268
        <comment>
269
            obsolete with spooler
270
        </comment>
271
    </note>
272
    <note priority="low" time="1099253109" done="1107927617">
273
        write combinator to catchALL and log all state etc. to disk
274
        <comment>
275
            duplicate of #28
276
        </comment>
277
    </note>
278
    <note priority="verylow" time="1099158901" done="1107739414">
279
        Generally prefix internal functions with _.
280
        <comment>
281
            Nope. Don't export internal functions.
282
        </comment>
283
    </note>
284
    <note priority="verylow" time="1099253172" done="1107927475">
285
        A 'fallback' combinator: "try f e $ either default return" or so
286
        <comment>
287
            implemented on top of catch
288
        </comment>
289
    </note>
290
    <note priority="veryhigh" time="1113867878">
291
        feeder doesn't flush '(CRLF).CRLF'.
292
    </note>
293
    <note priority="veryhigh" time="1113868224">
294
        handlePayload loses path to temporary file
295
    </note>
296
    <note priority="high" time="1108052773">
297
        Handle sha1 collisions in the spool
298
    </note>
299
    <note priority="high" time="1108680373">
300
        shutdown must be called by bracket
301
    </note>
302
    <note priority="medium" time="1098589904">
303
        Need combinator to catch and log the usual exceptions.
304
    </note>
305
    <note priority="medium" time="1098656105">
306
        Add an "InetAddress" type for IPv4 and v6 addresses.
307
308
        Also, a class interface which allows to convert all
309
        kinds of IP-address representations hence and forth
310
        between my type and HostAddr, SockAddr, etc.
311
    </note>
312
    <note priority="medium" time="1098726128">
313
        Need function to generate received headers
314
    </note>
315
    <note priority="medium" time="1100044460">
316
        deny private addresses (as mx, too)
317
    </note>
318
    <note priority="medium" time="1107998544">
319
        Move stuff from IO to FSM.Timeout
320
    </note>
321
    <note priority="low" time="1098656192">
322
        Find out how RTS settings affect the performance.
323
324
        Does the event handler benefit from caching? Or do
325
        we benefit from aggressive GC because it keeps our
326
        memory footprint small and ensures all finalizers
327
        are run quickly? (Currently, only ExternalHandle
328
        depends on finalizers.)
329
    </note>
330
    <note priority="low" time="1099252878">
331
        Make a prologue file for the haddock index page.
332
    </note>
333
    <note priority="low" time="1104539876">
334
        Need way to accept _all_ e-mail from trusted peers to avoid bounces.
335
    </note>
336
    <note priority="low" time="1119525523">
337
        Get rid of bracketOnError in Postmaster.Base.
338
    </note>
339
    <note priority="verylow" time="1097188529">
340
        Format log messages and map them to priorities.
341
    </note>
342
</todo>