Subversion Repositories Kolibri OS

Rev

Rev 914 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 914 Rev 2971
Line 1... Line 1...
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;;  SOCKET.INC                                                  ;;
6
;;  SOCKET.INC                                                  ;;
7
;;                                                              ;;
7
;;                                                              ;;
8
;;  Sockets constants, structures and functions                 ;;
8
;;  Sockets constants, structures and functions                 ;;
9
;;                                                              ;;
9
;;                                                              ;;
10
;;  Last revision: 11.11.2006                                   ;;
-
 
11
;;                                                              ;;
-
 
12
;;  This file contains the following:                           ;;
10
;;  This file contains the following:                           ;;
13
;;    is_localport_unused                                       ;;
11
;;    is_localport_unused                                       ;;
14
;;    get_free_socket                                           ;;
12
;;    get_free_socket                                           ;;
15
;;    socket_open                                               ;;
13
;;    socket_open                                               ;;
16
;;    socket_open_tcp                                           ;;
14
;;    socket_open_tcp                                           ;;
Line 27... Line 25...
27
;;   22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net          ;;
25
;;   22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net          ;;
28
;;   11.11.2006 - [Johnny_B] and [smb]                          ;;
26
;;   11.11.2006 - [Johnny_B] and [smb]                          ;;
29
;;                                                              ;;
27
;;                                                              ;;
30
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line 31... Line 29...
31
 
29
 
32
$Revision: 914 $
-
 
Line 33... Line -...
33
 
-
 
34
 
-
 
35
;
-
 
36
;  Socket Descriptor + Buffer
-
 
37
;
-
 
38
;    0                   1                   2                   3
-
 
39
;    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-
 
40
;
-
 
41
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
 
42
;  0|                    Status ( of this buffer )                  |
-
 
43
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
 
44
;  4|  Application Process ID                                       |
-
 
45
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
 
46
;  8|                  Local IP Address                             |
-
 
47
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
 
48
; 12| Local IP Port                 | Unused ( set to 0 )           |
-
 
49
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
 
50
; 16|                  Remote IP Address                            |
-
 
51
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
 
52
; 20| Remote IP Port                | Unused ( set to 0 )           |
-
 
53
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
 
54
; 24|   Rx Data Count                                   INTEL format|
-
 
55
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
 
56
; 28|                 TCB STATE                         INTEL format|
-
 
57
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
 
58
; 32|   TCB Timer (seconds)                             INTEL format|
-
 
59
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
 
60
; 36| ISS (Inital Sequence # used by this connection )   INET format|
-
 
61
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
 
62
; 40| IRS ( Inital Receive Sequence # )                  INET format|
-
 
63
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
 
64
; 44| SND.UNA  Seq # of unack'ed sent packets            INET format|
-
 
65
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
 
66
; 48| SND.NXT  Next send seq # to use                    INET format|
-
 
67
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
 
68
; 52| SND.WND  Send window                               INET format|
-
 
69
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
 
70
; 56| RCV.NXT  Next expected receive sequence #          INET format|
-
 
71
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
 
72
; 60| RCV.WND  Receive window                            INET format|
-
 
73
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
 
74
; 64| SEG.LEN  Segment length                           INTEL format|
-
 
75
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
 
76
; 68| SEG.WND  Segment window                           INTEL format|
-
 
77
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
 
78
; 72| Retransmit queue # NOW WINDOW SIZE TIMER          INTEL format|
-
 
79
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
 
80
; 76|       RX Data Buffer                                          |
-
 
81
;   +-+-+-..........                                               -+
-
 
82
 
30
$Revision: 2971 $
83
 
31
 
84
; so, define struct
-
 
85
struc SOCKET
32
; socket data structure
86
{
33
struct SOCKET
87
   .PrevPtr		    dd	 ?
34
  .PrevPtr	  dd ? ; pointer to previous socket in list
88
   .NextPtr		    dd	 ?
35
  .NextPtr	  dd ? ; pointer to next socket in list
89
   .Status		    dd	 ?  ;+00 - Status ( of this buffer )
36
  .Number	  dd ? ; socket number (unique within single process)
90
   .PID 		    dd	 ?  ;+04 - Application Process ID
37
  .PID		  dd ? ; application process id
91
   .LocalIP		    dd	 ?  ;+08 -  Local IP Address
38
  .LocalIP	  dd ? ; local IP address
92
   .LocalPort		    dw	 ?  ;+12 - Local Port
39
  .LocalPort	  dw ? ; local port
93
   .RemoteIP		    dd	 ?  ;+16 - Remote IP Address
40
  .RemoteIP	  dd ? ; remote IP address
94
   .RemotePort		    dw	 ?  ;+20 - Remote Port
41
  .RemotePort	  dw ? ; remote port
95
   .OrigRemoteIP	    dd	 ?
42
  .OrigRemoteIP   dd ? ; original remote IP address (used to reset to LISTEN state)
96
   .OrigRemotePort	    dw	 ?
43
  .OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state)
97
   .rxDataCount 	    dd	 ?  ;+24 - Rx Data Count
44
  .rxDataCount	  dd ? ; rx data count
98
   .TCBState		    dd	 ?  ;+28 - TCB STATE
45
  .TCBState	  dd ? ; TCB state
99
   .TCBTimer		    dd	 ?  ;+32 - TCB Timer (seconds)
46
  .TCBTimer	  dd ? ; TCB timer (seconds)
100
   .ISS 		    dd	 ?  ;+36 - Initial Send Sequence
47
  .ISS		  dd ? ; initial send sequence
101
   .IRS 		    dd	 ?  ;+40 - Initial Receive Sequence
48
  .IRS		  dd ? ; initial receive sequence
102
   .SND_UNA		    dd	 ?  ;+44 - Sequence number of unack'ed sent packets
49
  .SND_UNA	  dd ? ; sequence number of unack'ed sent packets
103
   .SND_NXT		    dd	 ?  ;+48 - Next send sequence number to use
50
  .SND_NXT	  dd ? ; bext send sequence number to use
104
   .SND_WND		    dd	 ?  ;+52 - Send window
51
  .SND_WND	  dd ? ; send window
105
   .RCV_NXT		    dd	 ?  ;+56 - Next receive sequence number to use
52
  .RCV_NXT	  dd ? ; next receive sequence number to use
106
   .RCV_WND		    dd	 ?  ;+60 - Receive window
53
  .RCV_WND	  dd ? ; receive window
107
   .SEG_LEN		    dd	 ?  ;+64 - Segment length
54
  .SEG_LEN	  dd ? ; segment length
108
   .SEG_WND		    dd	 ?  ;+68 - Segment window
-
 
109
   .wndsizeTimer	    dd	 ?  ;+72 - Retransmit queue # NOW WINDOW SIZE TIMER
-
 
110
   .rxData		    dd	 ?  ;+76 - receive data buffer here
-
 
111
}
-
 
112
 
-
 
113
virtual at 0
-
 
114
  SOCKET SOCKET
-
 
115
end virtual
-
 
116
 
-
 
117
; simple macro calcing real memory address of SOCKET struct by socket's
-
 
118
;macro   Index2RealAddr reg
55
  .SEG_WND	  dd ? ; segment window
119
;{
56
  .wndsizeTimer   dd ? ; window size timer
120
;        shl     reg, 12
57
  .lock           dd ? ; lock mutex
121
;    add     reg, sockets
-
 
122
;}
-
 
123
 
-
 
124
;Constants
-
 
125
; current socket statuses
-
 
Line 126... Line 58...
126
SOCK_EMPTY	   =	 0	  ; socket not in use
58
  .rxData	  dd ? ; receive data buffer here
127
SOCK_OPEN	   =	 1	  ; open issued, but no data sent
59
ends
128
 
60
 
Line -... Line 61...
-
 
61
; TCP opening modes
-
 
62
SOCKET_PASSIVE = 0
-
 
63
SOCKET_ACTIVE  = 1
-
 
64
 
-
 
65
; socket types
-
 
66
SOCK_STREAM = 1
-
 
67
SOCK_DGRAM  = 2
-
 
68
 
-
 
69
;; Allocate memory for socket data and put new socket into the list
-
 
70
; Newly created socket is initialized with calling PID and number and
129
; TCP opening modes
71
; put into beginning of list (which is a fastest way).
130
SOCKET_PASSIVE	   equ	   0
72
;
131
SOCKET_ACTIVE	   equ	   1
73
; @return socket structure address in EAX
132
 
74
;;
133
proc net_socket_alloc stdcall uses ebx ecx edx edi
75
proc net_socket_alloc stdcall uses ebx ecx edx edi
-
 
76
    mov ecx, SOCKETBUFFSIZE
134
    mov ecx, SOCKETBUFFSIZE
77
    mov edx, PG_SW
135
    mov edx, PG_SW
78
    call @mem_alloc@8
Line -... Line 79...
-
 
79
	DEBUGF	1, "K : net_socket_alloc (0x%x)\n", eax
136
    call @mem_alloc@8
80
	; check if we can allocate needed amount of memory
137
	DEBUGF	1, "K : net_socket_alloc (0x%x)\n", eax
81
	or	eax, eax
138
	or	eax, eax
82
	jz	.exit
139
	jz	.exit
83
 
140
 
84
	; zero-initialize allocated memory
141
	push	eax
85
	push	eax
142
	mov	edi, eax
86
	mov	edi, eax
Line -... Line 87...
-
 
87
	mov	ecx, SOCKETBUFFSIZE / 4
143
	mov	ecx, SOCKETBUFFSIZE / 4
88
	cld
144
	cld
89
	xor	eax, eax
145
	xor	eax, eax
90
	rep	stosd
146
	rep	stosd
91
	pop	eax
147
	pop	eax
92
 
148
 
93
	; add socket to the list by changing pointers
149
	mov	ebx, net_sockets
94
	mov	ebx, net_sockets
150
	push	[ebx + SOCKET.NextPtr]
95
	push	[ebx + SOCKET.NextPtr]
151
	mov	[ebx + SOCKET.NextPtr], eax
96
	mov	[ebx + SOCKET.NextPtr], eax
Line -... Line 97...
-
 
97
	mov	[eax + SOCKET.PrevPtr], ebx
152
	mov	[eax + SOCKET.PrevPtr], ebx
98
	pop	ebx
153
	pop	ebx
99
	mov	[eax + SOCKET.NextPtr], ebx
154
	mov	[eax + SOCKET.NextPtr], ebx
100
	or	ebx, ebx
Line -... Line 101...
-
 
101
	jz	@f
-
 
102
	mov	[ebx + SOCKET.PrevPtr], eax
-
 
103
 
-
 
104
    @@: ; set socket owner PID to the one of calling process
-
 
105
	mov	ebx, [TASK_BASE]
-
 
106
	mov	ebx, [ebx + TASKDATA.pid]
-
 
107
	mov	[eax + SOCKET.PID], ebx
-
 
108
 
-
 
109
	; find first free socket number and use it
-
 
110
	;mov     edx, ebx
-
 
111
	mov	ebx, net_sockets
-
 
112
	xor	ecx, ecx
-
 
113
  .next_socket_number:
-
 
114
	inc	ecx
-
 
115
  .next_socket:
-
 
116
	mov	ebx, [ebx + SOCKET.NextPtr]
-
 
117
	or	ebx, ebx
-
 
118
	jz	.last_socket_number
-
 
119
	cmp	[ebx + SOCKET.Number], ecx
-
 
120
	jne	.next_socket
155
	or	ebx, ebx
121
	;cmp     [ebx + SOCKET.PID], edx
156
	jz	@f
122
	;jne     .next_socket
157
	mov	[ebx + SOCKET.PrevPtr], eax
123
	mov	ebx, net_sockets
Line -... Line 124...
-
 
124
	jmp	.next_socket_number
-
 
125
 
-
 
126
  .last_socket_number:
-
 
127
	mov	[eax + SOCKET.Number], ecx
158
 
128
 
159
    @@: mov	ebx, [TASK_BASE]
129
  .exit:
160
	mov	ebx, [ebx + TASKDATA.pid]
130
	ret
-
 
131
endp
161
	mov	[eax + SOCKET.PID], ebx
132
 
162
 
133
;; Free socket data memory and pop socket off the list
Line -... Line 134...
-
 
134
;
163
  .exit:
135
; @param sockAddr is a socket structure address
164
	ret
136
;;
165
endp
137
proc net_socket_free stdcall uses ebx ecx edx, sockAddr:DWORD
166
 
138
	mov	eax, [sockAddr]
167
proc net_socket_free stdcall uses ebx ecx edx, sock:DWORD
139
	DEBUGF	1, "K : net_socket_free (0x%x)\n", eax
168
	mov	eax, [sock]
140
	; check if we got something similar to socket structure address
169
	DEBUGF	1, "K : net_socket_free (0x%x)\n", eax
141
	or	eax, eax
170
	or	eax, eax
142
	jz	.error
171
	jz	.error
143
 
172
 
144
	; make sure sockAddr is one of the socket addresses in the list
173
	mov	ebx, net_sockets
145
	mov	ebx, net_sockets
Line -... Line 146...
-
 
146
	;mov     ecx, [TASK_BASE]
-
 
147
	;mov     ecx, [ecx + TASKDATA.pid]
174
	mov	ecx, [TASK_BASE]
148
  .next_socket:
175
	mov	ecx, [ecx + TASKDATA.pid]
149
	mov	ebx, [ebx + SOCKET.NextPtr]
176
  .next_socket:
150
	or	ebx, ebx
177
	mov	ebx, [ebx + SOCKET.NextPtr]
151
	jz	.error
178
	or	ebx, ebx
152
	cmp	ebx, eax
Line 197... Line 171...
197
  .error:
171
  .error:
198
	DEBUGF	1, "K :   failed\n"
172
	DEBUGF	1, "K :   failed\n"
199
	ret
173
	ret
200
endp
174
endp
Line -... Line 175...
-
 
175
 
-
 
176
;; Get socket structure address by its number
-
 
177
; Scan through sockets list to find the socket with specified number.
-
 
178
; This proc uses SOCKET.PID indirectly to check if socket is owned by
-
 
179
; calling process.
-
 
180
;
-
 
181
; @param sockNum is a socket number
-
 
182
; @return socket structure address or 0 (not found) in EAX
201
 
183
;;
202
proc net_socket_num_to_addr stdcall uses ebx ecx, x:DWORD
184
proc net_socket_num_to_addr stdcall uses ebx ecx, sockNum:DWORD
-
 
185
	mov	eax, [sockNum]
203
; FIXME: do real transform
186
	; check if we got something similar to socket number
-
 
187
	or	eax, eax
-
 
188
	jz	.error
-
 
189
 
204
	mov	eax, [x]
190
	; scan through sockets list
205
	mov	ebx, net_sockets
191
	mov	ebx, net_sockets
206
	mov	ecx, [TASK_BASE]
192
	;mov     ecx, [TASK_BASE]
207
	mov	ecx, [ecx + TASKDATA.pid]
193
	;mov     ecx, [ecx + TASKDATA.pid]
208
  .next_socket:
194
  .next_socket:
209
	mov	ebx, [ebx + SOCKET.NextPtr]
195
	mov	ebx, [ebx + SOCKET.NextPtr]
210
	or	ebx, ebx
196
	or	ebx, ebx
211
	jz	.error
197
	jz	.error
212
	cmp	ebx, eax
198
	cmp	[ebx + SOCKET.Number], eax
213
	jne	.next_socket
199
	jne	.next_socket
214
	;cmp     [ebx + SOCKET.PID], ecx
200
	;cmp     [ebx + SOCKET.PID], ecx
-
 
201
	;jne     .next_socket
-
 
202
 
-
 
203
	; okay, we found the correct one
215
	;jne     .next_socket
204
	mov	eax, ebx
Line 216... Line 205...
216
	ret
205
	ret
217
 
206
 
218
  .error:
207
  .error:
219
	xor	eax, eax
208
	xor	eax, eax
Line -... Line 209...
-
 
209
	ret
-
 
210
endp
-
 
211
 
-
 
212
;; Get socket number by its structure address
-
 
213
; Scan through sockets list to find the socket with specified address.
-
 
214
; This proc uses SOCKET.PID indirectly to check if socket is owned by
-
 
215
; calling process.
-
 
216
;
220
	ret
217
; @param sockAddr is a socket structure address
221
endp
218
; @return socket number (SOCKET.Number) or 0 (not found) in EAX
-
 
219
;;
222
 
220
proc net_socket_addr_to_num stdcall uses ebx ecx, sockAddr:DWORD
-
 
221
	mov	eax, [sockAddr]
-
 
222
	; check if we got something similar to socket structure address
-
 
223
	or	eax, eax
223
proc net_socket_addr_to_num stdcall uses ebx ecx, x:DWORD
224
	jz	.error
224
; FIXME: do real transform
225
 
225
	mov	eax, [x]
226
	; scan through sockets list
226
	mov	ebx, net_sockets
227
	mov	ebx, net_sockets
227
	mov	ecx, [TASK_BASE]
228
	;mov     ecx, [TASK_BASE]
228
	mov	ecx, [ecx + TASKDATA.pid]
229
	;mov     ecx, [ecx + TASKDATA.pid]
229
  .next_socket:
230
  .next_socket:
230
	mov	ebx, [ebx + SOCKET.NextPtr]
231
	mov	ebx, [ebx + SOCKET.NextPtr]
231
	or	ebx, ebx
232
	or	ebx, ebx
232
	jz	.error
233
	jz	.error
233
	cmp	ebx, eax
234
	cmp	ebx, eax
-
 
235
	jne	.next_socket
-
 
236
	;cmp     [ebx + SOCKET.PID], ecx
-
 
237
	;jne     .next_socket
234
	jne	.next_socket
238
 
Line 235... Line 239...
235
	;cmp     [ebx + SOCKET.PID], ecx
239
	; okay, we found the correct one
236
	;jne     .next_socket
240
	mov	eax, [ebx + SOCKET.Number]
237
	ret
241
	ret
238
 
242
 
Line 239... Line 243...
239
  .error:
243
  .error:
240
	xor	eax, eax
-
 
241
	ret
244
	xor	eax, eax
242
endp
-
 
243
 
-
 
244
;***************************************************************************
245
	ret
245
;   Function
246
endp
246
;      is_localport_unused
247
 
247
;
-
 
248
;   Description
248
;; [53.9] Check if local port is used by any socket in the system.
249
;         scans through all the active sockets , looking to see if the
249
; Scan through sockets list, checking SOCKET.LocalPort.
-
 
250
; Useful when you want a to generate a unique local port number.
250
;      port number specified in bx is in use as a localport number.
251
; This proc doesn't guarantee that after calling it and trying to use
-
 
252
; the port reported being free in calls to socket_open/socket_open_tcp it'll
251
;      This is useful when you want a to generate a unique local port
253
; still be free or otherwise it'll still be used if reported being in use.
Line 252... Line 254...
252
;      number.
254
;
Line 253... Line 255...
253
;          On return, eax = 1 for free, 0 for in use
255
; @param BX is a port number
-
 
256
; @return 1 (port is free) or 0 (port is in use) in EAX
254
;
257
;;
255
;***************************************************************************
258
proc is_localport_unused stdcall
Line 256... Line 259...
256
proc is_localport_unused stdcall
259
 
257
 
260
	xchg	bl, bh
258
	xchg	bl, bh
261
 
259
 
262
	; assume the return value is 'free'
260
	xor	eax, eax			; Assume the return value is 'free'
263
	xor	eax, eax
261
	inc	al
264
	inc	al
Line 262... Line 265...
262
	mov	edx, net_sockets
265
	mov	edx, net_sockets
-
 
266
 
Line 263... Line 267...
263
 
267
  .next_socket:
264
  .next_socket:
268
	mov	edx, [edx + SOCKET.NextPtr]
265
	mov	edx, [edx + SOCKET.NextPtr]
269
	or	edx, edx
Line 266... Line -...
266
	or	edx, edx
-
 
267
	jz	.exit
-
 
268
	cmp	[edx + SOCKET.LocalPort], bx
-
 
269
	jne	.next_socket			; Return back if the port is not occupied
270
	jz	.exit
270
 
271
	cmp	[edx + SOCKET.LocalPort], bx
271
	dec	al				; return 'in use'
-
 
272
 
-
 
273
  .exit:
272
	jne	.next_socket
274
    ret
273
 
275
endp
274
	; return 'in use'
276
 
275
	dec	al
277
 
276
 
278
;***************************************************************************
-
 
279
;   Function
277
  .exit:
280
;      socket_open
278
    ret
281
;
279
endp
282
;   Description
280
 
Line 283... Line 281...
283
;       find a free socket
281
;; [53.0] Open DGRAM socket (connectionless, unreliable)
Line 284... Line 282...
284
;       local port in ebx
282
;
Line 285... Line -...
285
;       remote port in ecx
-
 
286
;       remote ip in edx
283
; @param BX is local port number
287
;       return socket # in eax, -1 if none available
284
; @param CX is remote port number
288
;
285
; @param EDX is remote IP address
289
;***************************************************************************
286
; @return socket number or -1 (error) in EAX
Line 314... Line 311...
314
	DEBUGF	1, "K : socket_open (fail)\n"
311
	DEBUGF	1, "K : socket_open (fail)\n"
315
	or	eax, -1
312
	or	eax, -1
316
    ret
313
    ret
317
endp
314
endp
Line 318... Line -...
318
 
-
 
319
 
315
 
320
;***************************************************************************
-
 
321
;   Function
-
 
322
;      socket_open_tcp
316
;; [53.5] Open STREAM socket (connection-based, sequenced, reliable, two-way)
323
;
-
 
324
;   Description
-
 
325
;       Opens a TCP socket in PASSIVE or ACTIVE mode
-
 
326
;       find a free socket
317
;
327
;       local port in ebx ( intel format )
318
; @param BX is local port number
328
;       remote port in ecx ( intel format )
319
; @param CX is remote port number
329
;       remote ip in edx ( in Internet byte order )
320
; @param EDX is remote IP address
330
;       Socket open mode in esi  ( SOCKET_PASSIVE or SOCKET_ACTIVE )
321
; @param ESI is open mode (SOCKET_ACTIVE, SOCKET_PASSIVE)
331
;       return socket # in eax, -1 if none available
322
; @return socket number or -1 (error) in EAX
332
;
-
 
333
;***************************************************************************
323
;;
334
proc socket_open_tcp stdcall
324
proc socket_open_tcp stdcall
Line 335... Line 325...
335
local sockAddr dd ?
325
local sockAddr dd ?
336
 
326
 
Line 367... Line 357...
367
	DEBUGF	1, "K : socket_open_tcp (0x%x)\n", eax
357
	DEBUGF	1, "K : socket_open_tcp (0x%x)\n", eax
Line 368... Line 358...
368
 
358
 
Line 369... Line 359...
369
	mov	[sockAddr], eax
359
	mov	[sockAddr], eax
370
 
-
 
371
    ; TODO - check this works!
360
 
Line 372... Line 361...
372
	;xxx: already 0 (intialized by net_socket_alloc)
361
    ; TODO - check this works!
373
	;mov     [eax + SOCKET.wndsizeTimer], 0     ; Reset the window timer.
362
	;mov     [eax + SOCKET.wndsizeTimer], 0     ; Reset the window timer.
374
 
363
 
Line 421... Line 410...
421
    ; increment SND.NXT in socket
410
    ; increment SND.NXT in socket
422
	add	esi, SOCKET.SND_NXT
411
	add	esi, SOCKET.SND_NXT
423
    call    inc_inet_esi
412
    call    inc_inet_esi
Line 424... Line 413...
424
 
413
 
425
  .exit:
-
 
426
	mov	ebx, [sockAddr]
-
 
427
	mov	[ebx + SOCKET.Status], SOCK_OPEN
414
  .exit:
428
	;pop     eax      ; Get the socket number back, so we can return it
415
	; Get the socket number back, so we can return it
429
	stdcall net_socket_addr_to_num, ebx
416
	stdcall net_socket_addr_to_num, [sockAddr]
Line 430... Line 417...
430
	ret
417
    ret
431
 
418
 
432
  .error:
419
  .error:
433
	DEBUGF	1, "K : socket_open_tcp (fail)\n"
420
	DEBUGF	1, "K : socket_open_tcp (fail)\n"
434
	or	eax, -1
421
	or	eax, -1
Line 435... Line -...
435
    ret
-
 
436
endp
-
 
437
 
-
 
438
 
422
    ret
439
;***************************************************************************
423
endp
440
;   Function
-
 
441
;      socket_close
424
 
442
;
425
;; [53.1] Close DGRAM socket
443
;   Description
426
;
444
;       socket # in ebx
-
 
445
;       returns 0 for ok, -1 for socket not open (fail)
427
; @param EBX is socket number
446
;
428
; @return 0 (closed successfully) or -1 (error) in EAX
447
;***************************************************************************
429
;;
448
proc socket_close stdcall
430
proc socket_close stdcall
449
	DEBUGF	1, "K : socket_close (0x%x)\n", ebx
431
	DEBUGF	1, "K : socket_close (0x%x)\n", ebx
Line 450... Line -...
450
	stdcall net_socket_num_to_addr, ebx
-
 
451
	or	eax, eax
-
 
452
	jz	.error
-
 
453
 
-
 
454
	cmp	[eax + SOCKET.Status], dword SOCK_EMPTY
432
	stdcall net_socket_num_to_addr, ebx
455
	jz	.error
-
 
456
 
-
 
457
    ; Clear the socket varaibles
-
 
458
	stdcall net_socket_free, eax
-
 
459
;        mov     edi, eax
-
 
Line 460... Line 433...
460
;        xor     eax, eax
433
	or	eax, eax
461
;        mov     ecx, SOCKETHEADERSIZE
434
	jz	.error
Line 462... Line 435...
462
;        cld
435
 
463
;        rep     stosb
436
	stdcall net_socket_free, eax
464
 
437
 
465
    xor     eax, eax
438
    xor     eax, eax
466
	ret
439
    ret
Line 467... Line -...
467
 
-
 
-
 
440
 
468
  .error:
441
  .error:
469
	DEBUGF	1, "K : socket_close (fail)\n"
-
 
470
	or	eax, -1
442
	DEBUGF	1, "K : socket_close (fail)\n"
471
    ret
443
	or	eax, -1
472
endp
-
 
473
 
444
    ret
474
 
445
endp
475
;***************************************************************************
446
 
476
;   Function
-
 
477
;      socket_close_tcp
447
;; [53.8] Close STREAM socket
478
;
448
; Closing TCP sockets takes time, so when you get successful return code
479
;   Description
449
; from this function doesn't always mean that socket is actually closed.
480
;       socket # in ebx
450
;
481
;       returns 0 for ok, -1 for socket not open (fail)
451
; @param EBX is socket number
Line 491... Line 461...
491
    mov     ecx, 0
461
    mov     ecx, 0
Line 492... Line 462...
492
 
462
 
493
  .next_resendq:
463
  .next_resendq:
494
    cmp     ecx, NUMRESENDENTRIES
464
    cmp     ecx, NUMRESENDENTRIES
495
	je	.last_resendq	    ; None left
-
 
496
	;cmp     [esi], bl                               ; XTODO: bl -> ebx
465
	je	.last_resendq	    ; None left
497
	cmp	[esi + 4], ebx
466
	cmp	[esi + 4], ebx
498
	je	@f		    ; found one
467
	je	@f		    ; found one
499
    inc     ecx
468
    inc     ecx
500
	add	esi, 8
469
	add	esi, 8
Line 501... Line -...
501
	jmp	.next_resendq
-
 
502
 
470
	jmp	.next_resendq
503
    ;@@: mov     byte[esi], 0xff                         ; XTODO: 0xff -> 0
471
 
504
    @@: mov	dword[esi + 4], 0
472
    @@: mov	dword[esi + 4], 0
505
	inc	ecx
473
	inc	ecx
Line 513... Line 481...
513
	or	eax, eax
481
	or	eax, eax
514
	jz	.error
482
	jz	.error
Line 515... Line 483...
515
 
483
 
516
	mov	ebx, eax
484
	mov	ebx, eax
517
	mov	[sockAddr], eax
-
 
518
	cmp	[ebx + SOCKET.Status], SOCK_EMPTY
-
 
Line 519... Line 485...
519
	je	.error
485
	mov	[sockAddr], eax
520
 
486
 
521
	cmp	[ebx + SOCKET.TCBState], TCB_LISTEN		;xxx
487
	cmp	[ebx + SOCKET.TCBState], TCB_LISTEN
522
	je	.destroy_tcb					;xxx
488
	je	.destroy_tcb
Line 523... Line 489...
523
	cmp	[ebx + SOCKET.TCBState], TCB_SYN_SENT		;xxx
489
	cmp	[ebx + SOCKET.TCBState], TCB_SYN_SENT
524
	je	.destroy_tcb					;xxx
490
	je	.destroy_tcb
525
 
491
 
526
    ; Now construct the response, and queue for sending by IP
492
    ; Now construct the response, and queue for sending by IP
527
    mov     eax, EMPTY_QUEUE
493
    mov     eax, EMPTY_QUEUE
Line 528... Line 494...
528
    call    dequeue
494
    call    dequeue
Line 529... Line -...
529
    cmp     ax, NO_BUFFER
-
 
530
	je	.error
495
    cmp     ax, NO_BUFFER
531
 
496
	je	.error
532
    push    eax
497
 
533
 
498
    push    eax
Line 534... Line 499...
534
;xxx    mov     bl, TH_FIN + TH_ACK
499
 
Line 543... Line 508...
543
    call    inc_inet_esi
508
    call    inc_inet_esi
Line 544... Line 509...
544
 
509
 
545
 
510
 
546
    ; Get the socket state
-
 
547
    mov     eax, [ebx + SOCKET.TCBState]
-
 
548
;xxx    cmp     eax, TCB_LISTEN
-
 
549
;xxx    je      .destroy_tcb
-
 
550
;xxx    cmp     eax, TCB_SYN_SENT
511
    ; Get the socket state
551
;xxx    je      .destroy_tcb
512
    mov     eax, [ebx + SOCKET.TCBState]
552
    cmp     eax, TCB_SYN_RECEIVED
513
    cmp     eax, TCB_SYN_RECEIVED
553
	je	.fin_wait_1
514
	je	.fin_wait_1
Line 554... Line 515...
554
    cmp     eax, TCB_ESTABLISHED
515
    cmp     eax, TCB_ESTABLISHED
555
	je	.fin_wait_1
516
	je	.fin_wait_1
556
 
-
 
557
    ; assume CLOSE WAIT
517
 
558
    ; Send a fin, then enter last-ack state
518
    ; assume CLOSE WAIT
Line 559... Line 519...
559
	; TODO: check if it's really a TCB_CLOSE_WAIT
519
    ; Send a fin, then enter last-ack state
560
	mov	[ebx + SOCKET.TCBState], TCB_LAST_ACK
520
	mov	[ebx + SOCKET.TCBState], TCB_LAST_ACK
Line 578... Line 538...
578
    pop     ebx
538
    pop     ebx
579
    call    queue
539
    call    queue
580
	jmp	.exit
540
	jmp	.exit
Line 581... Line 541...
581
 
541
 
582
  .destroy_tcb:
-
 
Line 583... Line 542...
583
;xxx    pop     eax
542
  .destroy_tcb:
584
 
-
 
585
	; Clear the socket variables
543
 
Line 586... Line 544...
586
;xxx    stdcall net_socket_free, [sockAddr]
544
	; Clear the socket variables
587
	stdcall net_socket_free, ebx
545
	stdcall net_socket_free, ebx
588
 
546
 
Line 594... Line 552...
594
	DEBUGF	1, "K : socket_close_tcp (fail)\n"
552
	DEBUGF	1, "K : socket_close_tcp (fail)\n"
595
	or	eax, -1
553
	or	eax, -1
596
    ret
554
    ret
597
endp
555
endp
Line 598... Line -...
598
 
-
 
599
 
-
 
600
;***************************************************************************
-
 
601
;   Function
556
 
602
;      socket_poll
-
 
603
;
-
 
604
;   Description
-
 
605
;       socket # in ebx
-
 
606
;       returns count in eax.
557
;; [53.2] Poll socket
-
 
558
;
607
;
559
; @param EBX is socket number
-
 
560
; @return count or bytes in rx buffer or 0 (error) in EAX
608
;***************************************************************************
561
;;
609
proc socket_poll stdcall
562
proc socket_poll stdcall
610
;        DEBUGF  1, "socket_poll(0x%x)\n", ebx
563
;        DEBUGF  1, "socket_poll(0x%x)\n", ebx
611
	stdcall net_socket_num_to_addr, ebx
564
	stdcall net_socket_num_to_addr, ebx
612
	or	eax, eax
565
	or	eax, eax
Line 613... Line 566...
613
	jz	.error
566
	jz	.error
614
 
567
 
Line 615... Line 568...
615
	mov	eax, [eax + SOCKET.rxDataCount]
568
	mov	eax, [eax + SOCKET.rxDataCount]
616
    ret
-
 
617
 
569
    ret
618
  .error:
570
 
619
	;or      eax, -1
571
  .error:
Line 620... Line -...
620
	xor	eax, eax
-
 
621
	ret
-
 
622
endp
-
 
623
 
572
	xor	eax, eax
624
 
-
 
625
;***************************************************************************
-
 
626
;   Function
-
 
627
;      socket_status
-
 
628
;
573
	ret
-
 
574
endp
629
;   Description
575
 
-
 
576
;; [53.6] Get socket TCB state
630
;       socket # in ebx
577
;
631
;       returns TCB state in eax.
578
; @param EBX is socket number
632
;
579
; @return socket TCB state or 0 (error) in EAX
633
;***************************************************************************
580
;;
634
proc socket_status stdcall
581
proc socket_status stdcall
Line 635... Line 582...
635
;;       DEBUGF  1, "socket_status(0x%x)\n", ebx
582
;;       DEBUGF  1, "socket_status(0x%x)\n", ebx
636
	stdcall net_socket_num_to_addr, ebx
583
	stdcall net_socket_num_to_addr, ebx
Line 637... Line 584...
637
	or	eax, eax
584
	or	eax, eax
638
	jz	.error
-
 
639
 
585
	jz	.error
640
	mov	eax, [eax + SOCKET.TCBState]
586
 
641
	ret
587
	mov	eax, [eax + SOCKET.TCBState]
Line 642... Line 588...
642
 
588
    ret
643
  .error:
589
 
644
	;or      eax, -1
-
 
645
	xor	eax, eax
-
 
646
    ret
-
 
647
endp
-
 
648
 
590
  .error:
649
;    Index2RealAddr ebx
-
 
650
;    mov     eax, [ebx + SOCKET.TCBState]
591
	xor	eax, eax
651
;
592
    ret
652
;    ret
593
endp
653
 
594
 
654
 
595
;; [53.3] Get one byte from rx buffer
655
;***************************************************************************
596
; This function can return 0 in two cases: if there's one byte read and
656
;   Function
-
 
657
;      socket_read
597
; non left, and if an error occured. Behavior should be changed and function
658
;
598
; shouldn't be used for now. Consider using [53.11] instead.
659
;   Description
599
;
660
;       socket # in ebx
600
; @param EBX is socket number
661
;       returns # of bytes remaining in eax, data in bl
601
; @return number of bytes left in rx buffer or 0 (error) in EAX
Line -... Line 602...
-
 
602
; @return byte read in BL
-
 
603
;;
-
 
604
proc socket_read stdcall
662
;
605
;        DEBUGF  1, "socket_read(0x%x)\n", ebx
663
;***************************************************************************
606
	stdcall net_socket_num_to_addr, ebx
664
proc socket_read stdcall
607
	or	eax, eax
665
;        DEBUGF  1, "socket_read(0x%x)\n", ebx
608
	jz	.error
Line 666... Line 609...
666
	stdcall net_socket_num_to_addr, ebx
609
 
667
	or	eax, eax
610
	lea	ebx, [eax + SOCKET.lock]
668
	jz	.error
611
	call	wait_mutex
669
 
612
 
670
	mov	ebx, eax
-
 
671
    mov     eax, [ebx + SOCKET.rxDataCount]	    ; get count of bytes
-
 
672
    test    eax, eax
-
 
673
	jz	.error
-
 
Line 674... Line 613...
674
 
613
	mov	ebx, eax
675
    dec     eax
614
    mov     eax, [ebx + SOCKET.rxDataCount]	    ; get count of bytes
676
    mov     esi, ebx		; esi is address of socket
615
    test    eax, eax
677
    mov     [ebx + SOCKET.rxDataCount], eax	    ; store new count
616
	jz	.error_release
-
 
617
 
-
 
618
    dec     eax
678
	;movzx   ebx, byte[ebx + SOCKET.rxData]  ; get the byte
619
    mov     esi, ebx		; esi is address of socket
-
 
620
    mov     [ebx + SOCKET.rxDataCount], eax	    ; store new count
-
 
621
	movzx	eax, byte[ebx + SOCKET.rxData]		; get the byte
-
 
622
 
-
 
623
	mov	ecx, SOCKETBUFFSIZE - SOCKET.rxData - 1
-
 
624
	lea	edi, [esi + SOCKET.rxData]
-
 
625
	lea	esi, [edi + 1]
Line 679... Line 626...
679
	movzx	ebx, byte[ebx + SOCKETHEADERSIZE]  ; get the byte
626
    cld
Line -... Line 627...
-
 
627
	push	ecx
-
 
628
	shr	ecx, 2
680
    add     esi, SOCKETHEADERSIZE
629
    rep     movsd
681
    mov     edi, esi
-
 
682
    inc     esi
-
 
683
 
630
	pop	ecx
684
    mov     ecx, (SOCKETBUFFSIZE - SOCKETHEADERSIZE) / 4
631
	and	ecx, 3
685
	lea	edi, [ebx + SOCKETHEADERSIZE]
632
	rep	movsb
Line 686... Line -...
686
	lea	esi, [edi + 1]
-
 
-
 
633
 
687
    cld
634
	mov	[ebx + SOCKET.lock], 0
688
    rep     movsd
635
	mov	ebx, eax
-
 
636
 
689
 
637
	ret
690
	ret
638
 
691
 
-
 
692
  .error:
639
  .error_release:
693
	;or      eax, -1
640
	mov	[ebx + SOCKET.lock], 0
694
	xor	eax, eax
641
  .error:
695
	xor	ebx, ebx
642
	xor	ebx, ebx
696
    ret
643
    ret
697
endp
-
 
698
 
644
endp
699
 
645
 
700
;***************************************************************************
646
;; [53.11] Get specified number of bytes from rx buffer
701
;   Function
647
; Number of bytes in rx buffer can be less than requested size. In this case,
702
;      socket_read_packet
648
; only available number of bytes is read.
Line -... Line 649...
-
 
649
; This function can return 0 in two cases: if there's no data to read, and if
-
 
650
; an error occured. Behavior should be changed.
-
 
651
;
703
;
652
; @param EBX is socket number
704
;   Description
653
; @param ECX is pointer to application buffer
705
;       socket # in ebx
654
; @param EDX is application buffer size (number of bytes to read)
706
;       datapointer # in ecx
655
; @return number of bytes read or 0 (error) in EAX
Line 729... Line 678...
729
    push    eax
678
    push    eax
730
    mov     eax, edx					   ; number of bytes we want to copy must be in eax
679
    mov     eax, edx					   ; number of bytes we want to copy must be in eax
731
	call	.start_copy				   ; copy to the application
680
	call	.start_copy				   ; copy to the application
Line 732... Line 681...
732
 
681
 
733
    mov     esi, ebx					   ; now we're going to copy the remaining bytes to the beginning
682
    mov     esi, ebx					   ; now we're going to copy the remaining bytes to the beginning
734
    add     esi, SOCKETHEADERSIZE			   ; we dont need to copy the header
683
	add	esi, SOCKET.rxData			   ; we dont need to copy the header
735
    mov     edi, esi					   ; edi is where we're going to copy to
684
    mov     edi, esi					   ; edi is where we're going to copy to
736
    add     esi, edx					   ; esi is from where we copy
685
    add     esi, edx					   ; esi is from where we copy
737
    pop     ecx 					   ; count of bytes we have left
686
    pop     ecx 					   ; count of bytes we have left
738
    push    ecx 					   ; push it again so we can re-use it later
687
    push    ecx 					   ; push it again so we can re-use it later
Line 742... Line 691...
742
    pop     ecx
691
    pop     ecx
743
    and     ecx, 3
692
    and     ecx, 3
744
    rep     movsb					   ; copy remaining bytes
693
    rep     movsb					   ; copy remaining bytes
Line 745... Line 694...
745
 
694
 
-
 
695
  .exit:
746
  .exit:
696
	mov	[ebx + SOCKET.lock], 0
Line 747... Line 697...
747
    ret 						   ; at last, exit
697
    ret 						   ; at last, exit
748
 
-
 
749
  .error:
698
 
750
	;or      eax, -1
699
  .error:
Line 751... Line 700...
751
	xor	eax, eax
700
	xor	eax, eax
752
	ret
701
	ret
753
 
702
 
754
  .copy_all_bytes:
703
  .copy_all_bytes:
-
 
704
    xor     esi, esi
755
    xor     esi, esi
705
    mov     [ebx + SOCKET.rxDataCount], esi		   ; store new count (zero)
Line 756... Line 706...
756
    mov     [ebx + SOCKET.rxDataCount], esi		   ; store new count (zero)
706
	call	.start_copy
757
	call	.start_copy
707
	mov	[ebx + SOCKET.lock], 0
758
	ret
708
	ret
759
 
709
 
760
  .start_copy:
710
  .start_copy:
761
	mov	edi, ecx
711
	mov	edi, ecx
762
	mov	esi, ebx
712
	mov	esi, ebx
763
    add     esi, SOCKETHEADERSIZE			   ; we dont need to copy the header
713
	add	esi, SOCKET.rxData			   ; we dont need to copy the header
764
    mov     ecx, eax					   ; eax is count of bytes
714
    mov     ecx, eax					   ; eax is count of bytes
Line 770... Line 720...
770
    and     ecx, 3
720
    and     ecx, 3
771
    rep     movsb					   ; copy the rest bytes
721
    rep     movsb					   ; copy the rest bytes
772
	retn						   ; exit, or go back to shift remaining bytes if any
722
	retn						   ; exit, or go back to shift remaining bytes if any
773
endp
723
endp
Line 774... Line -...
774
 
-
 
775
 
-
 
776
;***************************************************************************
-
 
777
;   Function
-
 
778
;      socket_write
-
 
779
;
-
 
780
;   Description
-
 
781
;       socket in ebx
-
 
782
;       # of bytes to write in ecx
-
 
783
;       pointer to data in edx
-
 
784
;       returns 0 in eax ok, -1 == failed ( invalid socket, or
724
 
785
;       could not queue IP packet )
725
;; [53.4] Send data through DGRAM socket
-
 
726
;
786
;
727
; @param EBX is socket number
-
 
728
; @param ECX is application data size (number of bytes to send)
-
 
729
; @param EDX is pointer to application data buffer
-
 
730
; @return 0 (sent successfully) or -1 (error) in EAX
787
;***************************************************************************
731
;;
788
proc socket_write stdcall
732
proc socket_write stdcall
789
;        DEBUGF  1, "socket_write(0x%x)\n", ebx
733
;        DEBUGF  1, "socket_write(0x%x)\n", ebx
790
	stdcall net_socket_num_to_addr, ebx		   ; get real socket address
734
	stdcall net_socket_num_to_addr, ebx		   ; get real socket address
791
	or	eax, eax
735
	or	eax, eax
Line 792... Line 736...
792
	jz	.error
736
	jz	.error
Line 793... Line -...
793
 
-
 
794
	mov	ebx, eax
-
 
795
 
-
 
796
    ; If the socket is invalid, return with an error code
-
 
797
	cmp	[ebx + SOCKET.Status], SOCK_EMPTY
737
 
798
	je	.error
738
	mov	ebx, eax
799
 
739
 
800
    mov     eax, EMPTY_QUEUE
740
    mov     eax, EMPTY_QUEUE
Line 938... Line 878...
938
  .error:
878
  .error:
939
	or	eax, -1
879
	or	eax, -1
940
    ret
880
    ret
941
endp
881
endp
Line 942... Line -...
942
 
-
 
943
 
-
 
944
;***************************************************************************
-
 
945
;   Function
882
 
946
;      socket_write_tcp
883
;; [53.7] Send data through STREAM socket
947
;
-
 
948
;   Description
884
;
949
;       socket in ebx
885
; @param EBX is socket number
950
;       # of bytes to write in ecx
886
; @param ECX is application data size (number of bytes to send)
951
;       pointer to data in edx
887
; @param EDX is pointer to application data buffer
952
;       returns 0 in eax ok, -1 == failed ( invalid socket, or
-
 
953
;       could not queue IP packet )
888
; @return 0 (sent successfully) or -1 (error) in EAX
954
;
-
 
955
;***************************************************************************
889
;;
956
proc socket_write_tcp stdcall
890
proc socket_write_tcp stdcall
Line 957... Line 891...
957
local sockAddr dd ?
891
local sockAddr dd ?
958
 
892
 
Line 962... Line 896...
962
	jz	.error
896
	jz	.error
Line 963... Line 897...
963
 
897
 
964
	mov	ebx, eax
898
	mov	ebx, eax
Line 965... Line -...
965
	mov	[sockAddr], ebx
-
 
966
 
-
 
967
    ; If the socket is invalid, return with an error code
-
 
968
	cmp	[ebx + SOCKET.Status], SOCK_EMPTY
-
 
969
	je	.error
899
	mov	[sockAddr], ebx
970
 
-
 
971
    ; If the sockets window timer is nonzero, do not queue packet
900
 
972
    ; TODO - done
901
    ; If the sockets window timer is nonzero, do not queue packet
Line 973... Line 902...
973
	cmp	[ebx + SOCKET.wndsizeTimer], 0
902
	cmp	[ebx + SOCKET.wndsizeTimer], 0
974
	jne	.error
903
	jne	.error
Line 997... Line 926...
997
    ; Check destination IP address.
926
    ; Check destination IP address.
998
    ; If it is the local host IP, route it back to IP_RX
927
    ; If it is the local host IP, route it back to IP_RX
Line 999... Line 928...
999
 
928
 
1000
    pop     ebx
929
    pop     ebx
1001
    push    ecx
-
 
Line -... Line 930...
-
 
930
    push    ecx
1002
    mov     eax, NET1OUT_QUEUE
931
 
1003
 
932
	mov	eax, NET1OUT_QUEUE
1004
    mov     edx, [stack_ip]
933
    mov     edx, [stack_ip]
1005
	mov	ecx, [sockAddr]
934
	mov	ecx, [sockAddr]
1006
	cmp	edx, [ecx + SOCKET.RemoteIP]
935
	cmp	edx, [ecx + SOCKET.RemoteIP]
Line 1029... Line 958...
1029
    mov     ecx, 0
958
    mov     ecx, 0
Line 1030... Line 959...
1030
 
959
 
1031
  .next_resendq:
960
  .next_resendq:
1032
    cmp     ecx, NUMRESENDENTRIES
961
    cmp     ecx, NUMRESENDENTRIES
1033
	je	.exit		   ; None found
-
 
1034
	;cmp     byte[esi], 0xff                                 ; XTODO: 0xff -> 0
962
	je	.exit		   ; None found
1035
	cmp	dword[esi + 4], 0
963
	cmp	dword[esi + 4], 0
1036
	je	@f		   ; found one
964
	je	@f		   ; found one
1037
    inc     ecx
965
    inc     ecx
1038
	add	esi, 8
966
	add	esi, 8
Line 1047... Line 975...
1047
    ;  retries count
975
    ;  retries count
1048
    ;  retry time
976
    ;  retry time
1049
    ;  fill IP buffer associated with this descriptor
977
    ;  fill IP buffer associated with this descriptor
Line 1050... Line 978...
1050
 
978
 
1051
	stdcall net_socket_addr_to_num, [sockAddr]
-
 
1052
	;mov     [esi], al                               ; XTODO: al -> eax
979
	stdcall net_socket_addr_to_num, [sockAddr]
1053
	mov	[esi + 4], eax
980
	mov	[esi + 4], eax
1054
	mov	byte[esi + 1], TCP_RETRIES
981
	mov	byte[esi + 1], TCP_RETRIES
Line 1055... Line 982...
1055
	mov	word[esi + 2], TCP_TIMEOUT
982
	mov	word[esi + 2], TCP_TIMEOUT