1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
|
/**********************************************************************/
/** Microsoft Windows **/
/** Copyright(c) Microsoft Corp., 1993 **/
/**********************************************************************/
/*
Timer.c
This module checks for active sessions on all adapters for send/receive
NCBs that have timed out.
A single timer is used for all adapters.
If a send times out, then the session will be aborted.
FILE HISTORY:
Johnl 23-Sep-1993 Created
*/
#include <nbtprocs.h>
#include <ctemacro.h>
CTETimer TimeoutTimer ;
/*******************************************************************
NAME: CheckForTimedoutNCBs
SYNOPSIS: Traverses list of all send/receive NCBs checking for
any that have reached their timeout point every half
second.
ENTRY: pEvent - Not used
pCont - Not used
RETURNS: TRUE if the timer successfully started, FALSE otherwise
NOTES: This is a self perpetuating function, each time it is called,
it schedules the timer again for a 1/2 second later to
call itself.
To get it going, it should be called once during
initialization
HISTORY:
Johnl 23-Sep-1993 Created
********************************************************************/
BOOL CheckForTimedoutNCBs( CTEEvent *pCTEEvent, PVOID pCont )
{
tNAMEADDR * pNameAddr ;
tCLIENTELE * pClientEle ;
tCONNECTELE * pConnectEle ;
LIST_ENTRY * pEntry ;
LIST_ENTRY * pEntryClient ;
LIST_ENTRY * pEntryConn ;
LIST_ENTRY * pEntryRcv ;
//
// Look for Receive NCBs first
//
for ( pEntry = NbtConfig.AddressHead.Flink ;
pEntry != &NbtConfig.AddressHead ;
pEntry = pEntry->Flink )
{
PLIST_ENTRY pEntryClient ;
tADDRESSELE * pAddrEle = CONTAINING_RECORD( pEntry,
tADDRESSELE,
Linkage ) ;
ASSERT( pAddrEle->Verify == NBT_VERIFY_ADDRESS ) ;
for ( pEntryClient = pAddrEle->ClientHead.Flink ;
pEntryClient != &pAddrEle->ClientHead ;
pEntryClient = pEntryClient->Flink )
{
tCLIENTELE * pClientEle = CONTAINING_RECORD( pEntryClient,
tCLIENTELE,
Linkage ) ;
PLIST_ENTRY pEntryConn ;
ASSERT( pClientEle->Verify == NBT_VERIFY_CLIENT ||
pClientEle->Verify == NBT_VERIFY_CLIENT_DOWN ) ;
for ( pEntryConn = pClientEle->ConnectActive.Flink ;
pEntryConn != &pClientEle->ConnectActive ;
pEntryConn = pEntryConn->Flink )
{
PRCV_CONTEXT prcvCont ;
pConnectEle = CONTAINING_RECORD( pEntryConn,
tCONNECTELE,
Linkage ) ;
ASSERT( pConnectEle->Verify == NBT_VERIFY_CONNECTION ||
pConnectEle->Verify == NBT_VERIFY_CONNECTION_DOWN ) ;
if ( pConnectEle->RTO == NCB_INFINITE_TIME_OUT ||
pConnectEle->state != NBT_SESSION_UP ||
IsListEmpty( &pConnectEle->RcvHead ) )
{
continue ;
}
//
// Note that we only check the first receive buffer because
// the timeout is for the next receive indication (and not
// how long this NCB has been waiting).
//
pEntryRcv = pConnectEle->RcvHead.Flink ;
prcvCont = CONTAINING_RECORD( pEntryRcv, RCV_CONTEXT, ListEntry ) ;
ASSERT( prcvCont->Signature == RCVCONT_SIGN ) ;
if ( prcvCont->RTO == NCB_TIMED_OUT )
{
RemoveEntryList( &prcvCont->ListEntry ) ;
CTEIoComplete( prcvCont->pNCB, STATUS_TIMEOUT, 0 ) ;
}
else
{
prcvCont->RTO-- ;
}
} // ConnectActive
} // Client
} // Address
//
// Now look for Send NCB time outs. Only connections that specified
// a timeout will be put on this list.
//
for ( pEntry = NbtConfig.SendTimeoutHead.Flink ;
pEntry != &NbtConfig.SendTimeoutHead ;
)
{
PSEND_CONTEXT pSendCont ;
pSendCont = CONTAINING_RECORD( pEntry, SEND_CONTEXT, ListEntry ) ;
pEntry = pEntry->Flink ; // get the next one
pSendCont->STO-- ;
if ( pSendCont->STO == NCB_TIMED_OUT )
{
//
// Assumes pSendCont is stored in ncb_reserve field of NCB
// This will remove it from the timeout list also.
//
CTEIoComplete( CONTAINING_RECORD( pSendCont, NCB, ncb_reserve ),
STATUS_TIMEOUT,
0 ) ;
// the above CTEIoComplete will trigger events from the transport
// which could modify the SendTimeout list before we reach this
// point. Best just to wait until things clear up.
break;
}
}
//
// Restart the timer for a half second from now
//
CTEInitTimer( &TimeoutTimer ) ;
return !!CTEStartTimer( &TimeoutTimer, 500, CheckForTimedoutNCBs, NULL ) ;
}
/*******************************************************************
NAME: StartRefreshTimer
SYNOPSIS: Start the refresh timer
This function was necessary because of this scenario:
No node type was defined in registry, so we defaulted to
BNODE and didn't start refresh timer.
Now, while we are still coming up, dhcp tells us we are
MSNODE. Shouldn't we start the refresh timer?
That's why this function.
HISTORY:
Koti 9-Jun-1994 Created
********************************************************************/
NTSTATUS StartRefreshTimer( VOID )
{
NTSTATUS status = STATUS_SUCCESS;
tTIMERQENTRY *pTimerEntry;
//
// make sure it's not bnode, and that timer really needs to be started
//
if (!(NodeType & BNODE) && (!NbtConfig.pRefreshTimer))
{
// the initial refresh rate until we can contact the name server
NbtConfig.MinimumTtl = NBT_INITIAL_REFRESH_TTL;
NbtConfig.sTimeoutCount = 0;
status = StartTimer(
NbtConfig.InitialRefreshTimeout,
NULL, // context value
NULL, // context2 value
RefreshTimeout,
NULL,
NULL,
0,
&pTimerEntry);
if ( !NT_SUCCESS( status ) )
return status ;
NbtConfig.pRefreshTimer = pTimerEntry;
}
return(STATUS_SUCCESS);
}
#ifdef CHICAGO
/*******************************************************************
NAME: StopTimeoutTimer
SYNOPSIS: Stops the timer that was set in CheckForTimedoutNCBs.
This is needed only for Chicago which can dynamically
unload vnbt.
HISTORY:
Koti 23-May-1994 Created
********************************************************************/
VOID StopTimeoutTimer( VOID )
{
CTEStopTimer( &TimeoutTimer );
}
#endif
|