Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1674 lines
53 KiB

  1. /*++
  2. Copyright (c) 1989-1993 Microsoft Corporation
  3. Module Name:
  4. spxconn.h
  5. Abstract:
  6. Author:
  7. Nikhil Kamkolkar (nikhilk) 11-November-1993
  8. Environment:
  9. Kernel mode
  10. Revision History:
  11. Sanjay Anand (SanjayAn) 5-July-1995
  12. Bug fixes - tagged [SA]
  13. --*/
  14. // Minimum value for RTT in ms.
  15. // Have these be a derivate of registry values.
  16. #define SPX_T1_MIN 200
  17. #define MAX_RETRY_DELAY 5000 // 5 seconds
  18. #define SPX_DEF_RENEG_RETRYCOUNT 1 // All reneg pkts except min sent once
  19. // Some types
  20. typedef enum
  21. {
  22. SPX_CALL_RECVLEVEL,
  23. SPX_CALL_TDILEVEL
  24. } SPX_CALL_LEVEL;
  25. typedef enum
  26. {
  27. SPX_REQ_DATA,
  28. SPX_REQ_ORDREL,
  29. SPX_REQ_DISC
  30. } SPX_SENDREQ_TYPE;
  31. // This structure is pointed to by the FsContext field in the FILE_OBJECT
  32. // for this Connection.
  33. #define CFREF_CREATE 0
  34. #define CFREF_VERIFY 1
  35. #define CFREF_INDICATION 2
  36. #define CFREF_BYCTX 3
  37. #define CFREF_BYID 4
  38. #define CFREF_ADDR 5
  39. #define CFREF_REQ 6
  40. #define CFREF_TIMER 7
  41. #define CFREF_PKTIZE 8
  42. #define CFREF_RECV 9
  43. #define CFREF_ABORTPKT 10
  44. #define CFREF_ERRORSTATE 11
  45. #define CFREF_FINDROUTE 12
  46. //
  47. // New state added to reflect an SPXI connection which is waiting for
  48. // a local disconnect after having indicated a RELEASE to AFD.
  49. //
  50. #define CFREF_DISCWAITSPX 13
  51. #define CFREF_TOTAL 14
  52. #define CFMAX_STATES 20
  53. typedef struct _SPX_CONN_FILE
  54. {
  55. #if DBG
  56. ULONG scf_RefTypes[CFREF_TOTAL];
  57. #if 0
  58. //
  59. // Disabled for now - to enable logging of states, move this array *after* the Type/Size;
  60. // a change in their offset can cause problems since we assume the offset to be less than
  61. // the size of an AddressFile structure. (see SpxTdiQueryInformation)
  62. //
  63. ULONG scf_StateBuffer[CFMAX_STATES];
  64. ULONG scf_NextStatePtr;
  65. #endif
  66. #endif
  67. CSHORT scf_Type;
  68. CSHORT scf_Size;
  69. // number of references to this object.
  70. ULONG scf_RefCount;
  71. // Linkage in device address file list. The connection can be on the device
  72. // connection list, address inactive/listen/active list.
  73. struct _SPX_CONN_FILE * scf_Next;
  74. struct _SPX_CONN_FILE * scf_AssocNext;
  75. struct _SPX_CONN_FILE * scf_GlobalActiveNext;
  76. // Queued in a global list, stays here from creation to destroy.
  77. struct _SPX_CONN_FILE * scf_GlobalNext;
  78. struct _SPX_CONN_FILE * scf_PktNext;
  79. struct _SPX_CONN_FILE * scf_ProcessRecvNext;
  80. // the current state of the connection. One main state and multiple substates.
  81. ULONG scf_Flags;
  82. // More information
  83. ULONG scf_Flags2;
  84. #if DBG
  85. // Save the state of flags/flags2 before reinit. Overwritten every reinit.
  86. ULONG scf_GhostFlags;
  87. ULONG scf_GhostFlags2;
  88. ULONG scf_GhostRefCount;
  89. PREQUEST scf_GhostDiscReq;
  90. #endif
  91. // Connection retry counts, or watchdog timer count when the connection goes
  92. // active
  93. union
  94. {
  95. LONG scf_CRetryCount;
  96. LONG scf_WRetryCount;
  97. };
  98. LONG scf_RRetryCount;
  99. USHORT scf_RRetrySeqNum;
  100. union
  101. {
  102. ULONG scf_CTimerId;
  103. ULONG scf_RTimerId; // Only after we turn active
  104. };
  105. ULONG scf_WTimerId; // Watchdog timer
  106. ULONG scf_TTimerId; // TDI Connect/Disconnect timer
  107. ULONG scf_ATimerId; // Ack timer id
  108. // Variables used to manage the Retry timer tick value
  109. // Note our timer subsytem fires at 100ms granularity.
  110. int scf_BaseT1;
  111. int scf_AveT1;
  112. int scf_DevT1;
  113. // Stored in HOST-ORDER
  114. // LOCAL variables
  115. USHORT scf_LocalConnId;
  116. USHORT scf_SendSeqNum; // Debug dw +9a
  117. USHORT scf_SentAllocNum; // dw +9c
  118. // REMOTE variables
  119. USHORT scf_RecvSeqNum; // dw +9e
  120. USHORT scf_RecdAckNum; // dw +a0
  121. USHORT scf_RecdAllocNum; // dw +a2
  122. // RETRY sequence number
  123. USHORT scf_RetrySeqNum;
  124. // Saved ack number to be used in building the reneg ack packet.
  125. // Note that our RecvSeqNum which we normally use is overwritten
  126. // when we receive a renegotiate request.
  127. USHORT scf_RenegAckAckNum;
  128. // Stored in NETWORK-ORDER. scf_RemAckAddr contains the remote address
  129. // for a data packet that had the ack bit set, buildAck will use this
  130. // address.
  131. BYTE scf_RemAddr[12];
  132. BYTE scf_RemAckAddr[12];
  133. USHORT scf_RemConnId; // Debug dw +be
  134. // Maximum packet size (or size of first) reneg packet.
  135. USHORT scf_RenegMaxPktSize;
  136. // Local target to use in when sending acks. This is set to received
  137. // data's indicated local target.
  138. IPX_LOCAL_TARGET scf_AckLocalTarget;
  139. // Maximum packet size to use for this connection
  140. USHORT scf_MaxPktSize;
  141. UCHAR scf_DataType;
  142. // Local target to use in sends, initialized upon connect indication
  143. // or when find_route completes
  144. IPX_LOCAL_TARGET scf_LocalTarget;
  145. // Connection lock
  146. CTELock scf_Lock;
  147. // address to which we are bound
  148. struct _SPX_ADDR_FILE * scf_AddrFile;
  149. // Connection context
  150. CONNECTION_CONTEXT scf_ConnCtx;
  151. #ifdef ISN_NT
  152. // easy backlink to file object.
  153. PFILE_OBJECT scf_FileObject;
  154. #endif
  155. // LIST_ENTRY of disconnect irps waiting for completion. There could be
  156. // multiple disconnect inform irps.
  157. LIST_ENTRY scf_DiscLinkage;
  158. // LIST_ENTRY of send requests (intially contains connect/listen/accept also)
  159. // on this connection.
  160. LIST_ENTRY scf_ReqLinkage;
  161. // Queue for completed requests awaiting completion
  162. LIST_ENTRY scf_ReqDoneLinkage;
  163. LIST_ENTRY scf_RecvDoneLinkage;
  164. // Queue for pending receives
  165. LIST_ENTRY scf_RecvLinkage;
  166. PREQUEST scf_CurRecvReq;
  167. ULONG scf_CurRecvOffset;
  168. ULONG scf_CurRecvSize;
  169. // Current request packetize info
  170. PREQUEST scf_ReqPkt;
  171. ULONG scf_ReqPktOffset;
  172. ULONG scf_ReqPktSize;
  173. ULONG scf_ReqPktFlags;
  174. SPX_SENDREQ_TYPE scf_ReqPktType;
  175. // Single linked list of sequenced send/disc packets
  176. PSPX_SEND_RESD scf_SendSeqListHead;
  177. PSPX_SEND_RESD scf_SendSeqListTail;
  178. // Single linked list of send (unsequenced) packets
  179. PSPX_SEND_RESD scf_SendListHead;
  180. PSPX_SEND_RESD scf_SendListTail;
  181. // Single linked list of buffered recv packets.
  182. PSPX_RECV_RESD scf_RecvListHead;
  183. PSPX_RECV_RESD scf_RecvListTail;
  184. // Connect request
  185. PREQUEST scf_ConnectReq;
  186. // This holds the request used to close this address file,
  187. // for pended completion. We also pend cleanup requests for connections.
  188. PREQUEST scf_CleanupReq;
  189. PREQUEST scf_CloseReq;
  190. #if DBG
  191. // Packet being indicated, seq num, flags/flags2
  192. USHORT scf_PktSeqNum;
  193. ULONG scf_PktFlags;
  194. ULONG scf_PktFlags2;
  195. ULONG scf_IndBytes;
  196. ULONG scf_IndLine;
  197. #endif
  198. #if DBG_WDW_CLOSE
  199. // Keep track of how long the window was closed on this connection.
  200. ULONG scf_WdwCloseAve;
  201. LARGE_INTEGER scf_WdwCloseTime; // Time when wdw was closed
  202. #endif
  203. // device to which we are attached.
  204. struct _DEVICE * scf_Device;
  205. } SPX_CONN_FILE, *PSPX_CONN_FILE;
  206. // Basic states
  207. // Least significant byte of flags is used.
  208. // Mutually exclusive states are coded as numbers, others are bit flags.
  209. // Only main states are currently in form of numbers. Also, send and receive.
  210. //
  211. // Once we go active, we need SEND/RECEIVE/DISC substates to be mutually
  212. // exclusive with each other. As all three could be active at the same time.
  213. // Connection MAIN states. These are all mutually exclusive.
  214. #define SPX_CONNFILE_MAINMASK 0x00000007
  215. #define SPX_CONNFILE_ACTIVE 0x00000001
  216. #define SPX_CONNFILE_CONNECTING 0x00000002
  217. #define SPX_CONNFILE_LISTENING 0x00000003
  218. #define SPX_CONNFILE_DISCONN 0x00000004
  219. // Connecting states (VALID when CONNFILE_CONNECTING)
  220. #define SPX_CONNECT_MASK 0x000000F0
  221. #define SPX_CONNECT_SENTREQ 0x00000010
  222. #define SPX_CONNECT_NEG 0x00000020
  223. #define SPX_CONNECT_W_SETUP 0x00000030
  224. // Listening states (VALID when CONNFILE_LISTENING)
  225. #define SPX_LISTEN_MASK 0x000000F0
  226. #define SPX_LISTEN_RECDREQ 0x00000010
  227. #define SPX_LISTEN_SENTACK 0x00000020
  228. #define SPX_LISTEN_NEGACK 0x00000030
  229. #define SPX_LISTEN_SETUP 0x00000040
  230. // Connection SUB states
  231. // Send machine states (VALID when CONNFILE_ACTIVE)
  232. #define SPX_SEND_MASK 0x000000F0
  233. #define SPX_SEND_IDLE 0x00000000
  234. #define SPX_SEND_PACKETIZE 0x00000010
  235. #define SPX_SEND_RETRY 0x00000020
  236. #define SPX_SEND_RETRYWD 0x00000030
  237. #define SPX_SEND_RENEG 0x00000040
  238. #define SPX_SEND_RETRY2 0x00000050
  239. #define SPX_SEND_RETRY3 0x00000060
  240. #define SPX_SEND_WD 0x00000070 // We dont reneg pkt size on wdog
  241. // Also we change to this state only
  242. // 2nd time wdog fires w/out ack.
  243. #define SPX_SEND_NAK_RECD 0x00000080
  244. // Receive machine states (VALID when CONNFILE_ACTIVE)
  245. #define SPX_RECV_MASK 0x00000F00
  246. #define SPX_RECV_IDLE 0x00000000
  247. #define SPX_RECV_POSTED 0x00000100
  248. #define SPX_RECV_PROCESS_PKTS 0x00000200
  249. // Disconnect states (VALID when CONNFILE_DISCONN/CONNFILE_ACTIVE)
  250. // These are valid when either ACTIVE/DISCONN is set. We use these when
  251. // active for a orderly release, i.e. we receive pkt from remote, but we
  252. // stay active (setting SPX_DISC_RECV_ORDREL) until our client posts a
  253. // disconnect, which is when we move to disconnecting.
  254. #define SPX_DISC_MASK 0x0000F000
  255. #define SPX_DISC_IDLE 0x00000000
  256. #define SPX_DISC_ABORT 0x00001000
  257. #define SPX_DISC_SENT_IDISC 0x00002000
  258. #define SPX_DISC_POST_ORDREL 0x00003000
  259. #define SPX_DISC_SENT_ORDREL 0x00004000
  260. #define SPX_DISC_ORDREL_ACKED 0x00005000
  261. #define SPX_DISC_POST_IDISC 0x00006000
  262. // [SA] bug #14655 added flag to indicate that SpxConnInactivate already called for
  263. // this disconnecting connection
  264. //
  265. #define SPX_DISC_INACTIVATED 0x00007000
  266. // The following are not mutually exclusive.
  267. #define SPX_CONNFILE_RECVQ 0x00010000 // Process completed receives/pkts
  268. #define SPX_CONNFILE_RENEG_SIZE 0x00020000 // Size changed in renegotiate pkt
  269. #define SPX_CONNFILE_ACKQ 0x00040000 // Waiting to piggyback ack queue
  270. #define SPX_CONNFILE_PKTQ 0x00080000 // Waiting to packetize queue
  271. #define SPX_CONNFILE_ASSOC 0x00100000 // associated
  272. #define SPX_CONNFILE_NEG 0x00200000 // CR had neg set (for delayed accept)
  273. #define SPX_CONNFILE_SPX2 0x00400000
  274. #define SPX_CONNFILE_STREAM 0x00800000
  275. #define SPX_CONNFILE_R_TIMER 0x01000000 // Retry timer (only after ACTIVE)
  276. #define SPX_CONNFILE_C_TIMER 0x01000000 // Connect timer
  277. #define SPX_CONNFILE_W_TIMER 0x02000000 // Watchdog timer
  278. #define SPX_CONNFILE_T_TIMER 0x04000000 // tdi connect/disc timer specified
  279. #define SPX_CONNFILE_RENEG_PKT 0x08000000 // Renegotiate changed size, repacketize
  280. #define SPX_CONNFILE_IND_IDISC 0x10000000 // Indicated abortive disc to afd
  281. #define SPX_CONNFILE_IND_ODISC 0x20000000 // Indicated orderly release to afd
  282. #define SPX_CONNFILE_STOPPING 0x40000000
  283. #define SPX_CONNFILE_CLOSING 0x80000000 // closing
  284. #define SPX_CONNFILE2_PKT_NOIND 0x00000001
  285. #define SPX_CONNFILE2_RENEGRECD 0x00000002 // A renegotiate was received.
  286. // scf_RenegAckAckNum set.
  287. #define SPX_CONNFILE2_PKT 0x00000004
  288. #define SPX_CONNFILE2_FINDROUTE 0x00000010 // A find route in progress on conn.
  289. #define SPX_CONNFILE2_NOACKWAIT 0x00000020 // Dont delay acks on connection, option
  290. #define SPX_CONNFILE2_IMMED_ACK 0x00000040 // Send an immediate ack,no back traffic
  291. #define SPX_CONNFILE2_IPXHDR 0x00000080 // Pass ipxhdr in receives
  292. //
  293. // [SA] Saves the IDisc flag passed to AbortiveDisc; this is TRUE only if there was
  294. // a remote disconnect on an SPX connection (in which case, we indicate TDI_DISCONNECT_RELEASE
  295. // else we indicate TDI_DISCONNECT_ABORT)
  296. //
  297. #define SPX_CONNFILE2_IDISC 0x00000100
  298. //
  299. // Indicates an SPXI connfile waiting for a local disconnect in response
  300. // to a TDI_DISCONNECT_RELEASE to AFD.
  301. //
  302. #define SPX_CONNFILE2_DISC_WAIT 0x00000200
  303. // FindRoute request structure
  304. typedef struct _SPX_FIND_ROUTE_REQUEST
  305. {
  306. // !!!!This must be the first element in the structure
  307. IPX_FIND_ROUTE_REQUEST fr_FindRouteReq;
  308. PVOID fr_Ctx;
  309. } SPX_FIND_ROUTE_REQUEST, *PSPX_FIND_ROUTE_REQUEST;
  310. typedef struct _SPX_CONNFILE_LIST
  311. {
  312. PSPX_CONN_FILE pcl_Head;
  313. PSPX_CONN_FILE pcl_Tail;
  314. } SPX_CONNFILE_LIST, *PSPX_CONNFILE_LIST;
  315. // Exported routines
  316. NTSTATUS
  317. SpxConnOpen(
  318. IN PDEVICE pDevice,
  319. IN CONNECTION_CONTEXT pConnCtx,
  320. IN PREQUEST pRequest);
  321. NTSTATUS
  322. SpxConnCleanup(
  323. IN PDEVICE Device,
  324. IN PREQUEST Request);
  325. NTSTATUS
  326. SpxConnClose(
  327. IN PDEVICE Device,
  328. IN PREQUEST Request);
  329. NTSTATUS
  330. SpxConnDisAssociate(
  331. IN PDEVICE pDevice,
  332. IN PREQUEST pRequest);
  333. NTSTATUS
  334. spxConnDisAssoc(
  335. IN PSPX_CONN_FILE pSpxConnFile,
  336. IN CTELockHandle LockHandleConn);
  337. VOID
  338. SpxConnStop(
  339. IN PSPX_CONN_FILE pSpxConnFile);
  340. NTSTATUS
  341. SpxConnAssociate(
  342. IN PDEVICE pDevice,
  343. IN PREQUEST pRequest);
  344. NTSTATUS
  345. SpxConnConnect(
  346. IN PDEVICE pDevice,
  347. IN PREQUEST pRequest);
  348. NTSTATUS
  349. SpxConnListen(
  350. IN PDEVICE pDevice,
  351. IN PREQUEST pRequest);
  352. NTSTATUS
  353. SpxConnAccept(
  354. IN PDEVICE pDevice,
  355. IN PREQUEST pRequest);
  356. NTSTATUS
  357. SpxConnAction(
  358. IN PDEVICE pDevice,
  359. IN PREQUEST pRequest);
  360. NTSTATUS
  361. SpxConnDisconnect(
  362. IN PDEVICE pDevice,
  363. IN PREQUEST pRequest);
  364. NTSTATUS
  365. SpxConnSend(
  366. IN PDEVICE pDevice,
  367. IN PREQUEST pRequest);
  368. NTSTATUS
  369. SpxConnRecv(
  370. IN PDEVICE pDevice,
  371. IN PREQUEST pRequest);
  372. VOID
  373. SpxConnFileRefByCtxLock(
  374. IN PSPX_ADDR_FILE pSpxAddrFile,
  375. IN CONNECTION_CONTEXT Ctx,
  376. OUT PSPX_CONN_FILE * ppSpxConnFile,
  377. OUT NTSTATUS * pStatus);
  378. NTSTATUS
  379. SpxConnFileVerify (
  380. IN PSPX_CONN_FILE pConnFile);
  381. VOID
  382. SpxConnFileDeref(
  383. IN PSPX_CONN_FILE pSpxConnFile);
  384. VOID
  385. SpxConnConnectFindRouteComplete(
  386. IN PSPX_CONN_FILE pSpxConnFile,
  387. IN PSPX_FIND_ROUTE_REQUEST pFrReq,
  388. IN BOOLEAN FoundRoute,
  389. IN CTELockHandle LockHandle);
  390. VOID
  391. SpxConnActiveFindRouteComplete(
  392. IN PSPX_CONN_FILE pSpxConnFile,
  393. IN PSPX_FIND_ROUTE_REQUEST pFrReq,
  394. IN BOOLEAN FoundRoute,
  395. IN CTELockHandle LockHandle);
  396. BOOLEAN
  397. SpxConnPacketize(
  398. IN PSPX_CONN_FILE pSpxConnFile,
  399. IN BOOLEAN fNormalState,
  400. IN CTELockHandle LockHandleConn);
  401. #if DBG
  402. VOID
  403. SpxConnFileRef(
  404. IN PSPX_CONN_FILE pSpxConnFile);
  405. VOID
  406. SpxConnFileLockRef(
  407. IN PSPX_CONN_FILE pSpxConnFile);
  408. #endif
  409. VOID
  410. SpxConnFileRefByIdLock (
  411. IN USHORT ConnId,
  412. OUT PSPX_CONN_FILE * ppSpxConnFile,
  413. OUT PNTSTATUS pStatus);
  414. BOOLEAN
  415. SpxConnDequeuePktLock(
  416. IN PSPX_CONN_FILE pSpxConnFile,
  417. IN PNDIS_PACKET pPkt);
  418. VOID
  419. SpxConnSendAck(
  420. IN PSPX_CONN_FILE pSpxConnFile,
  421. IN CTELockHandle LockHandleConn);
  422. VOID
  423. SpxConnSendNack(
  424. IN PSPX_CONN_FILE pSpxConnFile,
  425. IN USHORT NumToSend,
  426. IN CTELockHandle LockHandleConn);
  427. BOOLEAN
  428. SpxConnProcessAck(
  429. IN PSPX_CONN_FILE pSpxConnFile,
  430. IN PIPXSPX_HDR pAckHdr,
  431. IN CTELockHandle lockHandle);
  432. VOID
  433. SpxConnProcessRenegReq(
  434. IN PSPX_CONN_FILE pSpxConnFile,
  435. IN PIPXSPX_HDR pIpxSpxHdr,
  436. IN PIPX_LOCAL_TARGET pRemoteAddr,
  437. IN CTELockHandle lockHandle);
  438. VOID
  439. SpxConnProcessIDisc(
  440. IN PSPX_CONN_FILE pSpxConnFile,
  441. IN CTELockHandle lockHandle);
  442. VOID
  443. SpxConnProcessOrdRel(
  444. IN PSPX_CONN_FILE pSpxConnFile,
  445. IN CTELockHandle lockHandle);
  446. BOOLEAN
  447. SpxConnDequeueRecvPktLock(
  448. IN PSPX_CONN_FILE pSpxConnFile,
  449. IN PNDIS_PACKET pPkt);
  450. BOOLEAN
  451. SpxConnDequeueSendPktLock(
  452. IN PSPX_CONN_FILE pSpxConnFile,
  453. IN PNDIS_PACKET pPkt);
  454. // LOCAL functions
  455. VOID
  456. spxConnHandleConnReq(
  457. IN PIPXSPX_HDR pIpxSpxHdr,
  458. IN PIPX_LOCAL_TARGET pRemoteAddr);
  459. VOID
  460. spxConnHandleSessPktFromClient(
  461. IN PIPXSPX_HDR pIpxSpxHdr,
  462. IN PIPX_LOCAL_TARGET pRemoteAddr,
  463. IN PSPX_CONN_FILE pSpxConnFile);
  464. VOID
  465. spxConnHandleSessPktFromSrv(
  466. IN PIPXSPX_HDR pIpxSpxHdr,
  467. IN PIPX_LOCAL_TARGET pRemoteAddr,
  468. IN PSPX_CONN_FILE pSpxConnFile);
  469. ULONG
  470. spxConnConnectTimer(
  471. IN PVOID Context,
  472. IN BOOLEAN TimerShuttingDown);
  473. ULONG
  474. spxConnWatchdogTimer(
  475. IN PVOID Context,
  476. IN BOOLEAN TimerShuttingDown);
  477. ULONG
  478. spxConnRetryTimer(
  479. IN PVOID Context,
  480. IN BOOLEAN TimerShuttingDown);
  481. ULONG
  482. spxConnAckTimer(
  483. IN PVOID Context,
  484. IN BOOLEAN TimerShuttingDown);
  485. VOID
  486. spxConnCompletePended(
  487. IN PSPX_CONN_FILE pSpxConnFile);
  488. VOID
  489. SpxConnQWaitAck(
  490. IN PSPX_CONN_FILE pSpxConnFile);
  491. USHORT
  492. spxConnGetId(
  493. VOID);
  494. VOID
  495. spxConnInsertIntoActiveList(
  496. IN PSPX_ADDR pSpxAddr,
  497. IN PSPX_CONN_FILE pSpxConnFile);
  498. VOID
  499. spxConnInsertIntoInactiveList(
  500. IN PSPX_ADDR pSpxAddr,
  501. IN PSPX_CONN_FILE pSpxConnFile);
  502. NTSTATUS
  503. spxConnRemoveFromGlobalList(
  504. IN PSPX_CONN_FILE pSpxConnFile);
  505. VOID
  506. spxConnInsertIntoGlobalList(
  507. IN PSPX_CONN_FILE pSpxConnFile);
  508. NTSTATUS
  509. spxConnRemoveFromGlobalActiveList(
  510. IN PSPX_CONN_FILE pSpxConnFile);
  511. VOID
  512. spxConnPushIntoPktList(
  513. IN PSPX_CONN_FILE pSpxConnFile);
  514. VOID
  515. spxConnPopFromPktList(
  516. IN PSPX_CONN_FILE * ppSpxConnFile);
  517. VOID
  518. spxConnPushIntoRecvList(
  519. IN PSPX_CONN_FILE pSpxConnFile);
  520. VOID
  521. spxConnPopFromRecvList(
  522. IN PSPX_CONN_FILE * ppSpxConnFile);
  523. VOID
  524. spxConnInsertIntoGlobalActiveList(
  525. IN PSPX_CONN_FILE pSpxConnFile);
  526. VOID
  527. spxConnInsertIntoListenList(
  528. IN PSPX_ADDR pSpxAddr,
  529. IN PSPX_CONN_FILE pSpxConnFile);
  530. NTSTATUS
  531. spxConnRemoveFromList(
  532. IN PSPX_CONN_FILE * ppConnListHead,
  533. IN PSPX_CONN_FILE pConnRemove);
  534. NTSTATUS
  535. spxConnRemoveFromAssocList(
  536. IN PSPX_CONN_FILE * ppConnListHead,
  537. IN PSPX_CONN_FILE pConnRemove);
  538. VOID
  539. spxConnInactivate(
  540. IN PSPX_CONN_FILE pSpxConnFile);
  541. BOOLEAN
  542. spxConnGetPktByType(
  543. IN PSPX_CONN_FILE pSpxConnFile,
  544. IN ULONG PktType,
  545. IN BOOLEAN fSeqList,
  546. IN PNDIS_PACKET * ppPkt);
  547. BOOLEAN
  548. spxConnGetPktBySeqNum(
  549. IN PSPX_CONN_FILE pSpxConnFile,
  550. IN USHORT SeqNum,
  551. IN PNDIS_PACKET * ppPkt);
  552. VOID
  553. spxConnResendPkts(
  554. IN PSPX_CONN_FILE pSpxConnFile,
  555. IN CTELockHandle LockHandleConn);
  556. BOOLEAN
  557. spxConnCheckNegSize(
  558. IN PUSHORT pNegSize);
  559. VOID
  560. spxConnSetNegSize(
  561. IN OUT PNDIS_PACKET pPkt,
  562. IN ULONG Size);
  563. BOOLEAN
  564. spxConnAcceptCr(
  565. IN PSPX_CONN_FILE pSpxConnFile,
  566. IN PSPX_ADDR pSpxAddr,
  567. IN CTELockHandle LockHandleDev,
  568. IN CTELockHandle LockHandleAddr,
  569. IN CTELockHandle LockHandleConn);
  570. VOID
  571. spxConnAbortConnect(
  572. IN PSPX_CONN_FILE pSpxConnFile,
  573. IN NTSTATUS Status,
  574. IN CTELockHandle LockHandleDev,
  575. IN CTELockHandle LockHandleAddr,
  576. IN CTELockHandle LockHandleConn);
  577. VOID
  578. spxConnCompleteConnect(
  579. IN PSPX_CONN_FILE pSpxConnFile,
  580. IN CTELockHandle LockHandleDev,
  581. IN CTELockHandle LockHandleAddr,
  582. IN CTELockHandle LockHandleConn);
  583. VOID
  584. SpxConnQueueRecv(
  585. IN PSPX_CONN_FILE pSpxConnFile,
  586. IN PREQUEST pRequest);
  587. NTSTATUS
  588. spxConnProcessRecv(
  589. IN PSPX_CONN_FILE pSpxConnFile,
  590. IN PREQUEST pRequest,
  591. IN SPX_CALL_LEVEL CallLevel,
  592. IN CTELockHandle LockHandleConn);
  593. VOID
  594. spxConnProcessIndData(
  595. IN PSPX_CONN_FILE pSpxConnFile,
  596. IN SPX_CALL_LEVEL CallLevel,
  597. IN CTELockHandle LockHandleConn);
  598. NTSTATUS
  599. spxConnOrderlyDisc(
  600. IN PSPX_CONN_FILE pSpxConnFile,
  601. IN NTSTATUS Status,
  602. IN PREQUEST pRequest,
  603. IN CTELockHandle LockHandleConn);
  604. NTSTATUS
  605. spxConnInformedDisc(
  606. IN PSPX_CONN_FILE pSpxConnFile,
  607. IN NTSTATUS Status,
  608. IN PREQUEST pRequest,
  609. IN CTELockHandle LockHandleConn);
  610. VOID
  611. spxConnAbortiveDisc(
  612. IN PSPX_CONN_FILE pSpxConnFile,
  613. IN NTSTATUS Status,
  614. IN SPX_CALL_LEVEL CallLevel,
  615. IN CTELockHandle LockHandleConn,
  616. IN BOOLEAN Flag); // [SA] Bug #15249
  617. VOID
  618. spxConnAbortRecvs(
  619. IN PSPX_CONN_FILE pSpxConnFile,
  620. IN NTSTATUS Status,
  621. IN SPX_CALL_LEVEL CallLevel,
  622. IN CTELockHandle LockHandleConn);
  623. VOID
  624. spxConnAbortSends(
  625. IN PSPX_CONN_FILE pSpxConnFile,
  626. IN NTSTATUS Status,
  627. IN SPX_CALL_LEVEL CallLevel,
  628. IN CTELockHandle LockHandleConn);
  629. VOID
  630. spxConnResetSendQueue(
  631. IN PSPX_CONN_FILE pSpxConnFile);
  632. VOID
  633. spxConnAbortSendPkt(
  634. IN PSPX_CONN_FILE pSpxConnFile,
  635. IN PSPX_SEND_RESD pSendResd,
  636. IN SPX_CALL_LEVEL CallLevel,
  637. IN CTELockHandle LockHandleConn);
  638. BOOLEAN
  639. CheckSentPacket(
  640. PNDIS_PACKET npkt,
  641. UINT hlen,
  642. UINT len);
  643. //
  644. // MACROS
  645. //
  646. #define SHIFT100000 16
  647. #define SPX_CONVERT100NSTOCENTISEC(Li) \
  648. RtlExtendedMagicDivide((Li), Magic100000, SHIFT100000)
  649. #define UNSIGNED_BETWEEN_WITH_WRAP(Low, High, Target) \
  650. ((Low <= High) ? ((Target >= Low) && (Target <= High)) : \
  651. ((Target >= Low) || (Target <= High)))
  652. // This is with the assumption that the window size will never be greater
  653. // than the difference of 0x8000 and 0x1000. If High is < 1000 and Low
  654. // is > 8000 then we can assume a wrap happened. Otherwise, we assume no
  655. // wrap and do a straight compare.
  656. #define MAX_WINDOW_SIZE 0x6000
  657. #define DEFAULT_WINDOW_SIZE 8
  658. #define UNSIGNED_GREATER_WITH_WRAP(High, Low) \
  659. (((High < 0x1000) && (Low > 0x8000)) ? TRUE : (High > Low))
  660. #define SPX_SET_ACKNUM(pSpxConnFile, RecdAckNum, RecdAllocNum) \
  661. { \
  662. DBGPRINT(SEND, DBG, \
  663. ("SPX_SET_ACKNUM: %lx.%lx = %lx.%lx (%s.%d)\n", \
  664. (RecdAckNum), (RecdAllocNum), \
  665. ((pSpxConnFile)->scf_RecdAckNum), \
  666. ((pSpxConnFile)->scf_RecdAllocNum), \
  667. __FILE__, __LINE__)); \
  668. \
  669. if (UNSIGNED_GREATER_WITH_WRAP((RecdAckNum), \
  670. ((pSpxConnFile)->scf_RecdAckNum))) \
  671. { \
  672. (pSpxConnFile)->scf_RecdAckNum = (RecdAckNum); \
  673. } \
  674. \
  675. if (UNSIGNED_GREATER_WITH_WRAP((RecdAllocNum), \
  676. ((pSpxConnFile)->scf_RecdAllocNum)))\
  677. { \
  678. (pSpxConnFile)->scf_RecdAllocNum = (RecdAllocNum); \
  679. } \
  680. }
  681. #define BEGIN_PROCESS_PACKET(pSpxConnFile, seqNum) \
  682. { \
  683. SPX_CONN_SETFLAG2(pSpxConnFile, SPX_CONNFILE2_PKT); \
  684. }
  685. #define END_PROCESS_PACKET(pSpxConnFile, fBuffered, fSuccess) \
  686. { \
  687. SPX_CONN_RESETFLAG2(pSpxConnFile, \
  688. (SPX_CONNFILE2_PKT |SPX_CONNFILE2_RENEGRECD)); \
  689. if (fSuccess) \
  690. { \
  691. SPX_CONN_RESETFLAG2(pSpxConnFile, SPX_CONNFILE2_PKT_NOIND); \
  692. SPX_SET_RECVNUM(pSpxConnFile, fBuffered); \
  693. } \
  694. }
  695. #define INCREMENT_WINDOW(pSpxConnFile) \
  696. ((pSpxConnFile)->scf_SentAllocNum++)
  697. #define ADD_TO_WINDOW(pSpxConnFile, numPkts) \
  698. ((pSpxConnFile)->scf_SentAllocNum += (numPkts))
  699. #if DBG_WDW_CLOSE
  700. #define SPX_SET_RECVNUM(pSpxConnFile, fBuffered) \
  701. { \
  702. (pSpxConnFile)->scf_RecvSeqNum++; \
  703. if (!fBuffered) \
  704. (pSpxConnFile)->scf_SentAllocNum++; \
  705. \
  706. if (fBuffered && \
  707. (UNSIGNED_GREATER_WITH_WRAP( \
  708. (pSpxConnFile)->scf_RecvSeqNum, \
  709. (pSpxConnFile)->scf_SentAllocNum))) \
  710. { \
  711. KeQuerySystemTime( \
  712. (PLARGE_INTEGER)&pSpxConnFile->scf_WdwCloseTime); \
  713. } \
  714. }
  715. #else
  716. #define SPX_SET_RECVNUM(pSpxConnFile, fBuffered) \
  717. { \
  718. (pSpxConnFile)->scf_RecvSeqNum++; \
  719. if (!fBuffered) \
  720. (pSpxConnFile)->scf_SentAllocNum++; \
  721. }
  722. #endif
  723. #define SPX_CONN_SETNEXT_CUR_RECV(pSpxConnFile, pRequest) \
  724. { \
  725. RemoveEntryList(REQUEST_LINKAGE((pRequest))); \
  726. pSpxConnFile->scf_CurRecvReq = NULL; \
  727. pSpxConnFile->scf_CurRecvOffset = 0; \
  728. pSpxConnFile->scf_CurRecvSize = 0; \
  729. if (!IsListEmpty(&(pSpxConnFile)->scf_RecvLinkage)) \
  730. { \
  731. PTDI_REQUEST_KERNEL_RECEIVE _p; \
  732. DBGPRINT(RECEIVE, DBG, \
  733. ("spxConnProcessRecv: CURRECV %lx\n", pRequest)); \
  734. \
  735. (pSpxConnFile)->scf_CurRecvReq = \
  736. LIST_ENTRY_TO_REQUEST( \
  737. (pSpxConnFile)->scf_RecvLinkage.Flink); \
  738. \
  739. _p = (PTDI_REQUEST_KERNEL_RECEIVE) \
  740. REQUEST_PARAMETERS((pSpxConnFile)->scf_CurRecvReq); \
  741. \
  742. (pSpxConnFile)->scf_CurRecvOffset = 0; \
  743. (pSpxConnFile)->scf_CurRecvSize = (_p)->ReceiveLength; \
  744. } \
  745. if ((SPX_RECV_STATE(pSpxConnFile) == SPX_RECV_IDLE) || \
  746. (SPX_RECV_STATE(pSpxConnFile) == SPX_RECV_POSTED)) \
  747. { \
  748. SPX_RECV_SETSTATE( \
  749. pSpxConnFile, \
  750. (pSpxConnFile->scf_CurRecvReq == NULL) ? \
  751. SPX_RECV_IDLE : SPX_RECV_POSTED); \
  752. } \
  753. }
  754. #define SPX_INSERT_ADDR_ACTIVE(pSpxAddr, pSpxConnFile) \
  755. { \
  756. (pSpxConnFile)->scf_Next = (pSpxAddr)->sa_ActiveConnList; \
  757. (pSpxAddr)->sa_ActiveConnList = pSpxConnFile; \
  758. }
  759. #define SPX_INSERT_ADDR_INACTIVE(pSpxAddr, pSpxConnFile) \
  760. { \
  761. (pSpxConnFile)->scf_Next = (pSpxAddr)->sa_InactiveConnList; \
  762. (pSpxAddr)->sa_InactiveConnList = pSpxConnFile; \
  763. }
  764. #define SPX_INSERT_ADDR_LISTEN(pSpxAddr, pSpxConnFile) \
  765. { \
  766. (pSpxConnFile)->scf_Next = (pSpxAddr)->sa_ListenConnList; \
  767. (pSpxAddr)->sa_ListenConnList = pSpxConnFile; \
  768. }
  769. //
  770. // STATE MANIPULATION
  771. //
  772. #if 0
  773. //
  774. // Disabled for now
  775. //
  776. #define SPX_STORE_LAST_STATE(pSpxConnFile) \
  777. (pSpxConnFile)->scf_StateBuffer[(pSpxConnFile)->scf_NextStatePtr++] = \
  778. (pSpxConnFile)->scf_Flags; \
  779. (pSpxConnFile)->scf_NextStatePtr %= CFMAX_STATES;
  780. #else
  781. #define SPX_STORE_LAST_STATE(pSpxConnFile)
  782. #endif
  783. #define SPX_MAIN_STATE(pSpxConnFile) \
  784. ((pSpxConnFile)->scf_Flags & SPX_CONNFILE_MAINMASK)
  785. // #define SPX_CONN_IDLE(pSpxConnFile) \
  786. // ((BOOLEAN)(SPX_MAIN_STATE(pSpxConnFile) == 0))
  787. #define SPX_CONN_IDLE(pSpxConnFile) \
  788. ((BOOLEAN)((SPX_MAIN_STATE(pSpxConnFile) == 0) || \
  789. ((SPX_MAIN_STATE(pSpxConnFile) == SPX_CONNFILE_DISCONN) && \
  790. (SPX_DISC_STATE(pSpxConnFile) == SPX_DISC_INACTIVATED))))
  791. #define SPX_CONN_ACTIVE(pSpxConnFile) \
  792. ((BOOLEAN)(SPX_MAIN_STATE(pSpxConnFile) == SPX_CONNFILE_ACTIVE))
  793. #define SPX_CONN_CONNECTING(pSpxConnFile) \
  794. ((BOOLEAN)(SPX_MAIN_STATE(pSpxConnFile) == SPX_CONNFILE_CONNECTING))
  795. #define SPX_CONN_LISTENING(pSpxConnFile) \
  796. ((BOOLEAN)(SPX_MAIN_STATE(pSpxConnFile) == SPX_CONNFILE_LISTENING))
  797. #define SPX_CONN_DISC(pSpxConnFile) \
  798. ((BOOLEAN)(SPX_MAIN_STATE(pSpxConnFile) == SPX_CONNFILE_DISCONN))
  799. #if DBG
  800. #define SPX_MAIN_SETSTATE(pSpxConnFile, newState) \
  801. { \
  802. SPX_STORE_LAST_STATE(pSpxConnFile) \
  803. (pSpxConnFile)->scf_Flags = \
  804. (((pSpxConnFile)->scf_Flags & ~SPX_CONNFILE_MAINMASK) | (newState));\
  805. }
  806. #else
  807. #define SPX_MAIN_SETSTATE(pSpxConnFile, newState) \
  808. { \
  809. (pSpxConnFile)->scf_Flags = \
  810. (((pSpxConnFile)->scf_Flags & ~SPX_CONNFILE_MAINMASK) | (newState));\
  811. }
  812. #endif
  813. #define SPX_CONN_FLAG(pSpxConnFile, Flag) \
  814. ((BOOLEAN)(((pSpxConnFile)->scf_Flags & (Flag)) != 0))
  815. #define SPX_CONN_FLAG2(pSpxConnFile, Flag) \
  816. ((BOOLEAN)(((pSpxConnFile)->scf_Flags2 & (Flag)) != 0))
  817. #if DBG
  818. #define SPX_CONN_SETFLAG(pSpxConnFile, Flag) \
  819. SPX_STORE_LAST_STATE(pSpxConnFile) \
  820. ((pSpxConnFile)->scf_Flags |= (Flag))
  821. #else
  822. #define SPX_CONN_SETFLAG(pSpxConnFile, Flag) \
  823. ((pSpxConnFile)->scf_Flags |= (Flag))
  824. #endif
  825. #define SPX_CONN_SETFLAG2(pSpxConnFile, Flag) \
  826. ((pSpxConnFile)->scf_Flags2 |= (Flag))
  827. #define SPX_CONN_RESETFLAG(pSpxConnFile, Flag) \
  828. ((pSpxConnFile)->scf_Flags &= ~(Flag))
  829. #define SPX_CONN_RESETFLAG2(pSpxConnFile, Flag) \
  830. ((pSpxConnFile)->scf_Flags2 &= ~(Flag))
  831. #define SPX2_CONN(pSpxConnFile) \
  832. (SPX_CONN_FLAG((pSpxConnFile), SPX_CONNFILE_SPX2))
  833. #define SPX_CONN_STREAM(pSpxConnFile) \
  834. (SPX_CONN_FLAG((pSpxConnFile), SPX_CONNFILE_STREAM))
  835. #define SPX_CONN_MSG(pSpxConnFile) \
  836. (!SPX_CONN_FLAG((pSpxConnFile), SPX_CONNFILE_STREAM))
  837. #define SPX_LISTEN_STATE(pSpxConnFile) \
  838. ((pSpxConnFile)->scf_Flags & SPX_LISTEN_MASK)
  839. #define SPX_CONNECT_STATE(pSpxConnFile) \
  840. ((pSpxConnFile)->scf_Flags & SPX_CONNECT_MASK)
  841. #define SPX_SEND_STATE(pSpxConnFile) \
  842. ((pSpxConnFile)->scf_Flags & SPX_SEND_MASK)
  843. #define SPX_RECV_STATE(pSpxConnFile) \
  844. ((pSpxConnFile)->scf_Flags & SPX_RECV_MASK)
  845. #define SPX_DISC_STATE(pSpxConnFile) \
  846. ((pSpxConnFile)->scf_Flags & SPX_DISC_MASK)
  847. #if DBG
  848. #define SPX_LISTEN_SETSTATE(pSpxConnFile, newState) \
  849. { \
  850. DBGPRINT(STATE, INFO, \
  851. ("LISTEN: %x -> %x\n", \
  852. SPX_LISTEN_STATE(pSpxConnFile), (newState))); \
  853. DBGPRINT(STATE, INFO, \
  854. ("FILE: %s - %d\n", __FILE__, __LINE__)); \
  855. SPX_STORE_LAST_STATE(pSpxConnFile) \
  856. pSpxConnFile->scf_Flags = \
  857. (((pSpxConnFile)->scf_Flags & ~SPX_LISTEN_MASK) | (newState)); \
  858. }
  859. #define SPX_CONNECT_SETSTATE(pSpxConnFile, newState) \
  860. { \
  861. DBGPRINT(STATE, INFO, \
  862. ("CONNECT: %x -> %x\n", \
  863. SPX_CONNECT_STATE(pSpxConnFile), (newState))); \
  864. DBGPRINT(STATE, INFO, \
  865. ("FILE: %s - %d\n", __FILE__, __LINE__)); \
  866. SPX_STORE_LAST_STATE(pSpxConnFile) \
  867. (pSpxConnFile)->scf_Flags = \
  868. (((pSpxConnFile)->scf_Flags & ~SPX_CONNECT_MASK) | (newState)); \
  869. }
  870. #define SPX_SEND_SETSTATE(pSpxConnFile, newState) \
  871. { \
  872. DBGPRINT(STATE, INFO, \
  873. ("SEND: %x -> %x\n", \
  874. SPX_SEND_STATE(pSpxConnFile), (newState))); \
  875. DBGPRINT(STATE, INFO, \
  876. ("FILE: %s - %d\n", __FILE__, __LINE__)); \
  877. SPX_STORE_LAST_STATE(pSpxConnFile) \
  878. (pSpxConnFile)->scf_Flags = \
  879. (((pSpxConnFile)->scf_Flags & ~SPX_SEND_MASK) | (newState)); \
  880. }
  881. #define SPX_RECV_SETSTATE(pSpxConnFile, newState) \
  882. { \
  883. DBGPRINT(STATE, INFO, \
  884. ("RECV: %x -> %x\n", \
  885. SPX_RECV_STATE(pSpxConnFile), (newState))); \
  886. DBGPRINT(STATE, INFO, \
  887. ("FILE: %s - %d\n", __FILE__, __LINE__)); \
  888. SPX_STORE_LAST_STATE(pSpxConnFile) \
  889. (pSpxConnFile)->scf_Flags = \
  890. (((pSpxConnFile)->scf_Flags & ~SPX_RECV_MASK) | (newState)); \
  891. }
  892. #define SPX_DISC_SETSTATE(pSpxConnFile, newState) \
  893. { \
  894. DBGPRINT(STATE, INFO, \
  895. ("DISC: %x -> %x\n", \
  896. SPX_DISC_STATE(pSpxConnFile), (newState))); \
  897. DBGPRINT(STATE, INFO, \
  898. ("FILE: %s - %d\n", __FILE__, __LINE__)); \
  899. SPX_STORE_LAST_STATE(pSpxConnFile) \
  900. (pSpxConnFile)->scf_Flags = \
  901. (((pSpxConnFile)->scf_Flags & ~SPX_DISC_MASK) | (newState)); \
  902. }
  903. #else
  904. #define SPX_LISTEN_SETSTATE(pSpxConnFile, newState) \
  905. { \
  906. DBGPRINT(STATE, INFO, \
  907. ("LISTEN: %x -> %x\n", \
  908. SPX_LISTEN_STATE(pSpxConnFile), (newState))); \
  909. DBGPRINT(STATE, INFO, \
  910. ("FILE: %s - %d\n", __FILE__, __LINE__)); \
  911. pSpxConnFile->scf_Flags = \
  912. (((pSpxConnFile)->scf_Flags & ~SPX_LISTEN_MASK) | (newState)); \
  913. }
  914. #define SPX_CONNECT_SETSTATE(pSpxConnFile, newState) \
  915. { \
  916. DBGPRINT(STATE, INFO, \
  917. ("CONNECT: %x -> %x\n", \
  918. SPX_CONNECT_STATE(pSpxConnFile), (newState))); \
  919. DBGPRINT(STATE, INFO, \
  920. ("FILE: %s - %d\n", __FILE__, __LINE__)); \
  921. (pSpxConnFile)->scf_Flags = \
  922. (((pSpxConnFile)->scf_Flags & ~SPX_CONNECT_MASK) | (newState)); \
  923. }
  924. #define SPX_SEND_SETSTATE(pSpxConnFile, newState) \
  925. { \
  926. DBGPRINT(STATE, INFO, \
  927. ("SEND: %x -> %x\n", \
  928. SPX_SEND_STATE(pSpxConnFile), (newState))); \
  929. DBGPRINT(STATE, INFO, \
  930. ("FILE: %s - %d\n", __FILE__, __LINE__)); \
  931. (pSpxConnFile)->scf_Flags = \
  932. (((pSpxConnFile)->scf_Flags & ~SPX_SEND_MASK) | (newState)); \
  933. }
  934. #define SPX_RECV_SETSTATE(pSpxConnFile, newState) \
  935. { \
  936. DBGPRINT(STATE, INFO, \
  937. ("RECV: %x -> %x\n", \
  938. SPX_RECV_STATE(pSpxConnFile), (newState))); \
  939. DBGPRINT(STATE, INFO, \
  940. ("FILE: %s - %d\n", __FILE__, __LINE__)); \
  941. (pSpxConnFile)->scf_Flags = \
  942. (((pSpxConnFile)->scf_Flags & ~SPX_RECV_MASK) | (newState)); \
  943. }
  944. #define SPX_DISC_SETSTATE(pSpxConnFile, newState) \
  945. { \
  946. DBGPRINT(STATE, INFO, \
  947. ("DISC: %x -> %x\n", \
  948. SPX_DISC_STATE(pSpxConnFile), (newState))); \
  949. DBGPRINT(STATE, INFO, \
  950. ("FILE: %s - %d\n", __FILE__, __LINE__)); \
  951. (pSpxConnFile)->scf_Flags = \
  952. (((pSpxConnFile)->scf_Flags & ~SPX_DISC_MASK) | (newState)); \
  953. }
  954. #endif //DBG
  955. #define SpxConnQueueSendPktTail(pSpxConnFile, pPkt) \
  956. { \
  957. PSPX_SEND_RESD _pSendResd; \
  958. _pSendResd = (PSPX_SEND_RESD)((pPkt)->ProtocolReserved); \
  959. _pSendResd->sr_Next = NULL; \
  960. if ((pSpxConnFile)->scf_SendListTail != NULL) \
  961. { \
  962. (pSpxConnFile)->scf_SendListTail->sr_Next = _pSendResd; \
  963. (pSpxConnFile)->scf_SendListTail = _pSendResd;\
  964. } \
  965. else \
  966. { \
  967. (pSpxConnFile)->scf_SendListTail = \
  968. (pSpxConnFile)->scf_SendListHead = _pSendResd; \
  969. } \
  970. }
  971. #define SpxConnQueueSendPktHead(pSpxConnFile, pPkt) \
  972. { \
  973. PSPX_SEND_RESD _pSendResd; \
  974. _pSendResd = (PSPX_SEND_RESD)((pPkt)->ProtocolReserved); \
  975. _pSendResd->sr_Next = NULL; \
  976. if ((pSpxConnFile)->scf_SendListTail != NULL) \
  977. { \
  978. _pSendResd->sr_Next = (pSpxConnFile)->scf_SendListHead; \
  979. } \
  980. else \
  981. { \
  982. (pSpxConnFile)->scf_SendListTail = _pSendResd; \
  983. } \
  984. (pSpxConnFile)->scf_SendListHead = _pSendResd; \
  985. }
  986. #define SpxConnQueueSendSeqPktTail(pSpxConnFile, pPkt) \
  987. { \
  988. PSPX_SEND_RESD _pSendResd; \
  989. _pSendResd = (PSPX_SEND_RESD)((pPkt)->ProtocolReserved); \
  990. _pSendResd->sr_Next = NULL; \
  991. if ((pSpxConnFile)->scf_SendSeqListTail != NULL) \
  992. { \
  993. (pSpxConnFile)->scf_SendSeqListTail->sr_Next = _pSendResd;\
  994. (pSpxConnFile)->scf_SendSeqListTail = _pSendResd;\
  995. } \
  996. else \
  997. { \
  998. (pSpxConnFile)->scf_SendSeqListTail = \
  999. (pSpxConnFile)->scf_SendSeqListHead = _pSendResd; \
  1000. } \
  1001. }
  1002. #define SpxConnQueueSendSeqPktHead(pSpxConnFile, pPkt) \
  1003. { \
  1004. PSPX_SEND_RESD _pSendResd; \
  1005. _pSendResd = (PSPX_SEND_RESD)((pPkt)->ProtocolReserved); \
  1006. _pSendResd->sr_Next = NULL; \
  1007. if ((pSpxConnFile)->scf_SendSeqListTail != NULL) \
  1008. { \
  1009. _pSendResd->sr_Next = (pSpxConnFile)->scf_SendSeqListHead;\
  1010. } \
  1011. else \
  1012. { \
  1013. (pSpxConnFile)->scf_SendSeqListTail = _pSendResd; \
  1014. } \
  1015. (pSpxConnFile)->scf_SendSeqListHead = _pSendResd; \
  1016. }
  1017. #define SpxConnQueueRecvPktTail(pSpxConnFile, pPkt) \
  1018. { \
  1019. PSPX_RECV_RESD _pRecvResd; \
  1020. _pRecvResd = (PSPX_RECV_RESD)((pPkt)->ProtocolReserved); \
  1021. _pRecvResd->rr_Next = NULL; \
  1022. if ((pSpxConnFile)->scf_RecvListTail != NULL) \
  1023. { \
  1024. (pSpxConnFile)->scf_RecvListTail->rr_Next = _pRecvResd; \
  1025. (pSpxConnFile)->scf_RecvListTail = _pRecvResd;\
  1026. } \
  1027. else \
  1028. { \
  1029. (pSpxConnFile)->scf_RecvListTail = \
  1030. (pSpxConnFile)->scf_RecvListHead = _pRecvResd; \
  1031. } \
  1032. }
  1033. #define SpxConnQueueRecvPktHead(pSpxConnFile, pPkt) \
  1034. { \
  1035. PSPX_RECV_RESD _pRecvResd; \
  1036. _pRecvResd = (PSPX_RECV_RESD)((pPkt)->ProtocolReserved); \
  1037. _pRecvResd->rr_Next = NULL; \
  1038. if ((pSpxConnFile)->scf_RecvListTail != NULL) \
  1039. { \
  1040. _pRecvResd->rr_Next = (pSpxConnFile)->scf_RecvListHead; \
  1041. } \
  1042. else \
  1043. { \
  1044. (pSpxConnFile)->scf_RecvListTail = _pRecvResd; \
  1045. } \
  1046. (pSpxConnFile)->scf_RecvListHead = _pRecvResd; \
  1047. }
  1048. #if DBG
  1049. #define SpxConnFileReference(_ConnFile, _Type) \
  1050. { \
  1051. (VOID)SPX_ADD_ULONG ( \
  1052. &(_ConnFile)->scf_RefTypes[_Type], \
  1053. 1, \
  1054. &SpxGlobalInterlock); \
  1055. SpxConnFileRef (_ConnFile); \
  1056. }
  1057. #define SpxConnFileLockReference(_ConnFile, _Type) \
  1058. { \
  1059. (VOID)SPX_ADD_ULONG ( \
  1060. &(_ConnFile)->scf_RefTypes[_Type], \
  1061. 1, \
  1062. &SpxGlobalInterlock); \
  1063. SpxConnFileLockRef (_ConnFile); \
  1064. }
  1065. #define SpxConnFileDereference(_ConnFile, _Type) \
  1066. { \
  1067. (VOID)SPX_ADD_ULONG ( \
  1068. &(_ConnFile)->scf_RefTypes[_Type], \
  1069. (ULONG)-1, \
  1070. &SpxGlobalInterlock); \
  1071. SpxConnFileDeref (_ConnFile); \
  1072. }
  1073. #define SpxConnFileReferenceByCtx(_pAddrFile, _Ctx, _ppConnFile, _pStatus) \
  1074. { \
  1075. CTELockHandle _lockHandle; \
  1076. CTEGetLock((_pAddrFile)->saf_AddrLock, &(_lockHandle)); \
  1077. SpxConnFileRefByCtxLock((_pAddrFile), (_Ctx), (_ppConnFile),(_pStatus));\
  1078. CTEFreeLock((_pAddrFile)->saf_AddrLock, (_lockHandle)); \
  1079. }
  1080. #define SpxConnFileReferenceByCtxLock(_pAddrFile, _Ctx, _ppConnFile, _pStatus) \
  1081. SpxConnFileRefByCtxLock((_pAddrFile), (_Ctx), (_ppConnFile),(_pStatus));
  1082. #define SpxConnFileReferenceById(_ConnId, _ppConnFile, _pStatus) \
  1083. { \
  1084. CTELockHandle _l; \
  1085. CTEGetLock(&SpxDevice->dev_Lock, &(_l)); \
  1086. SpxConnFileRefByIdLock(_ConnId, _ppConnFile, _pStatus); \
  1087. CTEFreeLock(&SpxDevice->dev_Lock, _l); \
  1088. }
  1089. #define SpxConnFileTransferReference(_ConnFile, _OldType, _NewType) \
  1090. { \
  1091. (VOID)SPX_ADD_ULONG ( \
  1092. &(_ConnFile)->scf_RefTypes[_NewType], \
  1093. 1, \
  1094. &SpxGlobalInterlock); \
  1095. (VOID)SPX_ADD_ULONG ( \
  1096. &(_ConnFile)->scf_RefTypes[_OldType], \
  1097. (ULONG)-1, \
  1098. &SpxGlobalInterlock); \
  1099. }
  1100. #else // DBG
  1101. #define SpxConnFileReference(_ConnFile, _Type) \
  1102. SPX_ADD_ULONG( \
  1103. &(_ConnFile)->scf_RefCount, \
  1104. 1, \
  1105. &(_ConnFile)->scf_Lock)
  1106. #define SpxConnFileLockReference(_ConnFile, _Type) \
  1107. SPX_ADD_ULONG( \
  1108. &(_ConnFile)->scf_RefCount, \
  1109. 1, \
  1110. &(_ConnFile)->scf_Lock);
  1111. #define SpxConnFileDereference(_ConnFile, _Type) \
  1112. { \
  1113. SpxConnFileDeref(_ConnFile); \
  1114. }
  1115. #define SpxConnFileReferenceByCtx(_pAddrFile, _Ctx, _ppConnFile, _pStatus) \
  1116. { \
  1117. CTELockHandle _lockHandle; \
  1118. CTEGetLock((_pAddrFile)->saf_AddrLock, &(_lockHandle)); \
  1119. SpxConnFileRefByCtxLock((_pAddrFile), (_Ctx), (_ppConnFile),(_pStatus));\
  1120. CTEFreeLock((_pAddrFile)->saf_AddrLock, (_lockHandle)); \
  1121. }
  1122. #define SpxConnFileReferenceByCtxLock(_pAddrFile, _Ctx, _ppConnFile, _pStatus) \
  1123. SpxConnFileRefByCtxLock((_pAddrFile), (_Ctx), (_ppConnFile),(_pStatus));
  1124. #define SpxConnFileReferenceById(_ConnId, _ppConnFile, _pStatus) \
  1125. { \
  1126. CTELockHandle _lockHandle; \
  1127. CTEGetLock(&SpxDevice->dev_Lock, &(_lockHandle)); \
  1128. SpxConnFileRefByIdLock(_ConnId, _ppConnFile, _pStatus); \
  1129. CTEFreeLock(&SpxDevice->dev_Lock, (_lockHandle)); \
  1130. }
  1131. #define SpxConnFileTransferReference(_ConnFile, _OldType, _NewType)
  1132. #endif // DBG
  1133. // Set the packet size. If we are spx1 or spx2 and !neg, check if we are different
  1134. // nets, set to min then, else use the size indicated by IPX. If we are spx2, just
  1135. // set it to our local max.
  1136. //
  1137. // Also always even out packet size and round down. This solves an issue with
  1138. // data size needing to be even for some novell 802.2 clients.
  1139. //
  1140. // Fix after beta2 for tokring using receive size. Only if spx2 and neg.
  1141. #if defined(_PNP_POWER)
  1142. #define SPX_MAX_PKT_SIZE(pSpxConnFile, fSpx2Neg, fSpx2, pRemNet) \
  1143. { \
  1144. if (!fSpx2 && PARAM(CONFIG_BACKCOMP_SPX)) { \
  1145. (pSpxConnFile)->scf_MaxPktSize = SPX_MAX_PACKET; \
  1146. } \
  1147. else { \
  1148. IPX_LINE_INFO _i; \
  1149. \
  1150. (VOID)(*IpxQuery)( \
  1151. IPX_QUERY_LINE_INFO, \
  1152. &(pSpxConnFile)->scf_LocalTarget.NicHandle, \
  1153. &(_i), \
  1154. sizeof(IPX_LINE_INFO), \
  1155. NULL); \
  1156. \
  1157. (pSpxConnFile)->scf_MaxPktSize = (USHORT) (_i).MaximumPacketSize; \
  1158. if (!fSpx2Neg) \
  1159. { \
  1160. (pSpxConnFile)->scf_MaxPktSize = (USHORT) (_i).MaximumSendSize; \
  1161. } \
  1162. \
  1163. if ((pSpxConnFile)->scf_MaxPktSize < SPX_MAX_PACKET) \
  1164. { \
  1165. (pSpxConnFile)->scf_MaxPktSize = SPX_MAX_PACKET; \
  1166. } \
  1167. \
  1168. DBGPRINT(CONNECT, DBG, \
  1169. ("SPX_MAX_PKT_SIZE: Nets %lx.%lx Max Pkt %d\n", \
  1170. (*(UNALIGNED ULONG *)(pRemNet)), \
  1171. *(UNALIGNED ULONG *)SpxDevice->dev_Network, \
  1172. (pSpxConnFile)->scf_MaxPktSize)); \
  1173. DBGPRINT(CONNECT, DBG, \
  1174. ("%s : %d.%d\n", __FILE__, __LINE__, fSpx2Neg)); \
  1175. \
  1176. if ((!fSpx2Neg) && \
  1177. ((*(UNALIGNED ULONG *)(pRemNet)) != 0) && \
  1178. ((*(UNALIGNED ULONG *)SpxDevice->dev_Network) != 0) && \
  1179. ((*(UNALIGNED ULONG *)(pRemNet)) != \
  1180. *(UNALIGNED ULONG *)SpxDevice->dev_Network)) \
  1181. { \
  1182. if (PARAM(CONFIG_ROUTER_MTU) != 0) \
  1183. { \
  1184. DBGPRINT(CONNECT, ERR, \
  1185. ("SPX_MAX_PKT_SIZE: PARAM %lx Max Pkt %lx\n", \
  1186. PARAM(CONFIG_ROUTER_MTU), \
  1187. (pSpxConnFile)->scf_MaxPktSize)); \
  1188. \
  1189. (pSpxConnFile)->scf_MaxPktSize = \
  1190. (USHORT)(MIN(PARAM(CONFIG_ROUTER_MTU), \
  1191. (ULONG)((pSpxConnFile)->scf_MaxPktSize)));\
  1192. } \
  1193. else \
  1194. { \
  1195. (pSpxConnFile)->scf_MaxPktSize = SPX_MAX_PACKET; \
  1196. } \
  1197. \
  1198. DBGPRINT(CONNECT, DBG, \
  1199. ("SPX_MAX_PKT_SIZE: Nets %lx.%lx Max Pkt %d\n", \
  1200. (*(UNALIGNED ULONG *)(pRemNet)), \
  1201. *(UNALIGNED ULONG *)SpxDevice->dev_Network, \
  1202. (pSpxConnFile)->scf_MaxPktSize)); \
  1203. DBGPRINT(CONNECT, DBG, \
  1204. ("SPX_MAX_PKT_SIZE: LineInfo Pkt %d\n", \
  1205. (_i).MaximumSendSize)); \
  1206. } \
  1207. } \
  1208. (pSpxConnFile)->scf_MaxPktSize &= ~((USHORT)1); \
  1209. DBGPRINT(CONNECT, DBG, \
  1210. ("SPX_MAX_PKT_SIZE: %lx.%d\n", \
  1211. (pSpxConnFile)->scf_MaxPktSize, \
  1212. (pSpxConnFile)->scf_MaxPktSize)); \
  1213. }
  1214. #else
  1215. #define SPX_MAX_PKT_SIZE(pSpxConnFile, fSpx2Neg, fSpx2, pRemNet) \
  1216. { \
  1217. if (!fSpx2 && PARAM(CONFIG_BACKCOMP_SPX)) { \
  1218. (pSpxConnFile)->scf_MaxPktSize = SPX_MAX_PACKET; \
  1219. } \
  1220. else { \
  1221. IPX_LINE_INFO _i; \
  1222. \
  1223. (VOID)(*IpxQuery)( \
  1224. IPX_QUERY_LINE_INFO, \
  1225. (pSpxConnFile)->scf_LocalTarget.NicId, \
  1226. &(_i), \
  1227. sizeof(IPX_LINE_INFO), \
  1228. NULL); \
  1229. \
  1230. (pSpxConnFile)->scf_MaxPktSize = (_i).MaximumPacketSize; \
  1231. if (!fSpx2Neg) \
  1232. { \
  1233. (pSpxConnFile)->scf_MaxPktSize = (_i).MaximumSendSize; \
  1234. } \
  1235. \
  1236. if ((pSpxConnFile)->scf_MaxPktSize < SPX_MAX_PACKET) \
  1237. { \
  1238. (pSpxConnFile)->scf_MaxPktSize = SPX_MAX_PACKET; \
  1239. } \
  1240. \
  1241. DBGPRINT(CONNECT, DBG, \
  1242. ("SPX_MAX_PKT_SIZE: Nets %lx.%lx Max Pkt %d\n", \
  1243. (*(UNALIGNED ULONG *)(pRemNet)), \
  1244. *(UNALIGNED ULONG *)SpxDevice->dev_Network, \
  1245. (pSpxConnFile)->scf_MaxPktSize)); \
  1246. DBGPRINT(CONNECT, DBG, \
  1247. ("%s : %d.%d\n", __FILE__, __LINE__, fSpx2Neg)); \
  1248. \
  1249. if ((!fSpx2Neg) && \
  1250. ((*(UNALIGNED ULONG *)(pRemNet)) != 0) && \
  1251. ((*(UNALIGNED ULONG *)SpxDevice->dev_Network) != 0) && \
  1252. ((*(UNALIGNED ULONG *)(pRemNet)) != \
  1253. *(UNALIGNED ULONG *)SpxDevice->dev_Network)) \
  1254. { \
  1255. if (PARAM(CONFIG_ROUTER_MTU) != 0) \
  1256. { \
  1257. DBGPRINT(CONNECT, ERR, \
  1258. ("SPX_MAX_PKT_SIZE: PARAM %lx Max Pkt %lx\n", \
  1259. PARAM(CONFIG_ROUTER_MTU), \
  1260. (pSpxConnFile)->scf_MaxPktSize)); \
  1261. \
  1262. (pSpxConnFile)->scf_MaxPktSize = \
  1263. (USHORT)(MIN(PARAM(CONFIG_ROUTER_MTU), \
  1264. (ULONG)((pSpxConnFile)->scf_MaxPktSize)));\
  1265. } \
  1266. else \
  1267. { \
  1268. (pSpxConnFile)->scf_MaxPktSize = SPX_MAX_PACKET; \
  1269. } \
  1270. \
  1271. DBGPRINT(CONNECT, DBG, \
  1272. ("SPX_MAX_PKT_SIZE: Nets %lx.%lx Max Pkt %d\n", \
  1273. (*(UNALIGNED ULONG *)(pRemNet)), \
  1274. *(UNALIGNED ULONG *)SpxDevice->dev_Network, \
  1275. (pSpxConnFile)->scf_MaxPktSize)); \
  1276. DBGPRINT(CONNECT, DBG, \
  1277. ("SPX_MAX_PKT_SIZE: LineInfo Pkt %d\n", \
  1278. (_i).MaximumSendSize)); \
  1279. } \
  1280. } \
  1281. (pSpxConnFile)->scf_MaxPktSize &= ~((USHORT)1); \
  1282. DBGPRINT(CONNECT, DBG, \
  1283. ("SPX_MAX_PKT_SIZE: %lx.%d\n", \
  1284. (pSpxConnFile)->scf_MaxPktSize, \
  1285. (pSpxConnFile)->scf_MaxPktSize)); \
  1286. }
  1287. #endif _PNP_POWER
  1288. #if DBG
  1289. #define SPX_SENDPACKET(pSpxConnFile, pNdisPkt, pSendResd) \
  1290. { \
  1291. NDIS_STATUS _n; \
  1292. \
  1293. ++SpxDevice->dev_Stat.PacketsSent; \
  1294. \
  1295. _n = (*IpxSendPacket)( \
  1296. &(pSpxConnFile)->scf_LocalTarget, \
  1297. (pNdisPkt), \
  1298. (pSendResd)->sr_Len, \
  1299. (pSendResd)->sr_HdrLen); \
  1300. \
  1301. if (_n != NDIS_STATUS_PENDING) \
  1302. { \
  1303. if (_n != NDIS_STATUS_SUCCESS) \
  1304. { \
  1305. DBGPRINT(SEND, ERR, \
  1306. ("SPX_SENDPACKET: Failed with %lx in %s.%lx\n", \
  1307. _n, __FILE__, __LINE__)); \
  1308. } \
  1309. \
  1310. SpxSendComplete( \
  1311. (pNdisPkt), \
  1312. _n); \
  1313. } \
  1314. }
  1315. #define SPX_SENDACK(pSpxConnFile, pNdisPkt, pSendResd) \
  1316. { \
  1317. NDIS_STATUS _n; \
  1318. \
  1319. ++SpxDevice->dev_Stat.PacketsSent; \
  1320. \
  1321. _n = (*IpxSendPacket)( \
  1322. &(pSpxConnFile)->scf_AckLocalTarget, \
  1323. (pNdisPkt), \
  1324. (pSendResd)->sr_Len, \
  1325. (pSendResd)->sr_HdrLen); \
  1326. \
  1327. if (_n != NDIS_STATUS_PENDING) \
  1328. { \
  1329. if (_n != NDIS_STATUS_SUCCESS) \
  1330. { \
  1331. DBGPRINT(SEND, ERR, \
  1332. ("SPX_SENDPACKET: Failed with %lx in %s.%lx\n", \
  1333. _n, __FILE__, __LINE__)); \
  1334. } \
  1335. \
  1336. SpxSendComplete( \
  1337. (pNdisPkt), \
  1338. _n); \
  1339. } \
  1340. }
  1341. #else // DBG
  1342. #define SPX_SENDPACKET(pSpxConnFile, pNdisPkt, pSendResd) \
  1343. { \
  1344. NDIS_STATUS _n; \
  1345. \
  1346. ++SpxDevice->dev_Stat.PacketsSent; \
  1347. \
  1348. _n = (*IpxSendPacket)( \
  1349. &(pSpxConnFile)->scf_LocalTarget, \
  1350. (pNdisPkt), \
  1351. (pSendResd)->sr_Len, \
  1352. (pSendResd)->sr_HdrLen); \
  1353. \
  1354. if (_n != NDIS_STATUS_PENDING) \
  1355. { \
  1356. SpxSendComplete( \
  1357. (pNdisPkt), \
  1358. _n); \
  1359. } \
  1360. }
  1361. #define SPX_SENDACK(pSpxConnFile, pNdisPkt, pSendResd) \
  1362. { \
  1363. NDIS_STATUS _n; \
  1364. \
  1365. ++SpxDevice->dev_Stat.PacketsSent; \
  1366. \
  1367. _n = (*IpxSendPacket)( \
  1368. &(pSpxConnFile)->scf_AckLocalTarget, \
  1369. (pNdisPkt), \
  1370. (pSendResd)->sr_Len, \
  1371. (pSendResd)->sr_HdrLen); \
  1372. \
  1373. if (_n != NDIS_STATUS_PENDING) \
  1374. { \
  1375. SpxSendComplete( \
  1376. (pNdisPkt), \
  1377. _n); \
  1378. } \
  1379. }
  1380. #endif // DBG
  1381. #define SPX_QUEUE_FOR_RECV_COMPLETION(pSpxConnFile) \
  1382. { \
  1383. if (!SPX_CONN_FLAG( \
  1384. (pSpxConnFile), \
  1385. SPX_CONNFILE_RECVQ)) \
  1386. { \
  1387. SPX_CONN_SETFLAG((pSpxConnFile), SPX_CONNFILE_RECVQ); \
  1388. SpxConnFileLockReference(pSpxConnFile, CFREF_RECV); \
  1389. SPX_QUEUE_TAIL_RECVLIST(pSpxConnFile); \
  1390. } \
  1391. }
  1392. #define SPX_QUEUE_TAIL_PKTLIST(pSpxConnFile) \
  1393. { \
  1394. if (SpxPktConnList.pcl_Tail) \
  1395. { \
  1396. SpxPktConnList.pcl_Tail->scf_PktNext = pSpxConnFile; \
  1397. SpxPktConnList.pcl_Tail = pSpxConnFile; \
  1398. } \
  1399. else \
  1400. { \
  1401. SpxPktConnList.pcl_Tail = \
  1402. SpxPktConnList.pcl_Head = pSpxConnFile; \
  1403. } \
  1404. }
  1405. #define SPX_QUEUE_TAIL_RECVLIST(pSpxConnFile) \
  1406. { \
  1407. if (SpxRecvConnList.pcl_Tail) \
  1408. { \
  1409. SpxRecvConnList.pcl_Tail->scf_ProcessRecvNext = pSpxConnFile; \
  1410. SpxRecvConnList.pcl_Tail = pSpxConnFile; \
  1411. } \
  1412. else \
  1413. { \
  1414. SpxRecvConnList.pcl_Tail = \
  1415. SpxRecvConnList.pcl_Head = pSpxConnFile; \
  1416. } \
  1417. }