Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1159 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
3251 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved.    ;;
1159 hidnplayr 4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
3143 hidnplayr 6
;;  Part of the TCP/IP network stack for KolibriOS                 ;;
2888 hidnplayr 7
;;                                                                 ;;
8
;;   Written by hidnplayr@kolibrios.org,                           ;;
1529 hidnplayr 9
;;     and Clevermouse.                                            ;;
1159 hidnplayr 10
;;                                                                 ;;
1529 hidnplayr 11
;;       Based on code by mike.dld                                 ;;
1159 hidnplayr 12
;;                                                                 ;;
1529 hidnplayr 13
;;         GNU GENERAL PUBLIC LICENSE                              ;;
14
;;          Version 2, June 1991                                   ;;
15
;;                                                                 ;;
1159 hidnplayr 16
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17
 
1206 hidnplayr 18
$Revision: 3267 $
1159 hidnplayr 19
 
1773 hidnplayr 20
 
2402 hidnplayr 21
struct  SOCKET
1249 hidnplayr 22
 
2402 hidnplayr 23
        NextPtr                 dd ? ; pointer to next socket in list
24
        PrevPtr                 dd ? ; pointer to previous socket in list
25
        Number                  dd ? ; socket number
1249 hidnplayr 26
 
2402 hidnplayr 27
        mutex                   MUTEX
1249 hidnplayr 28
 
3264 hidnplayr 29
        PID                     dd ? ; process ID
30
        TID                     dd ? ; thread ID
3251 hidnplayr 31
        Domain                  dd ? ; INET/LOCAL/..
2402 hidnplayr 32
        Type                    dd ? ; RAW/STREAM/DGRAP
33
        Protocol                dd ? ; ICMP/IPv4/ARP/TCP/UDP
34
        errorcode               dd ?
3251 hidnplayr 35
        device                  dd ? ; driver pointer, socket pointer if it's an LOCAL socket
1249 hidnplayr 36
 
2402 hidnplayr 37
        options                 dd ?
38
        state                   dd ?
3251 hidnplayr 39
        backlog                 dw ? ; how many incoming connections that can be queued
1249 hidnplayr 40
 
2402 hidnplayr 41
        snd_proc                dd ?
42
        rcv_proc                dd ?
1536 hidnplayr 43
 
2305 hidnplayr 44
ends
1249 hidnplayr 45
 
2402 hidnplayr 46
struct  IP_SOCKET               SOCKET
1254 hidnplayr 47
 
2995 hidnplayr 48
        LocalIP                 rd 4 ; network byte order
49
        RemoteIP                rd 4 ; network byte order
1318 hidnplayr 50
 
2305 hidnplayr 51
ends
1159 hidnplayr 52
 
2402 hidnplayr 53
struct  TCP_SOCKET              IP_SOCKET
1249 hidnplayr 54
 
2995 hidnplayr 55
        LocalPort               dw ? ; network byte order
56
        RemotePort              dw ? ; network byte order
1514 hidnplayr 57
 
2402 hidnplayr 58
        t_state                 dd ? ; TCB state
2955 hidnplayr 59
        t_rxtshift              db ?
60
                                rb 3 ; align
2402 hidnplayr 61
        t_rxtcur                dd ?
62
        t_dupacks               dd ?
63
        t_maxseg                dd ?
64
        t_force                 dd ?
65
        t_flags                 dd ?
1514 hidnplayr 66
 
67
;---------------
68
; RFC783 page 21
69
 
70
; send sequence
2402 hidnplayr 71
        SND_UNA                 dd ? ; sequence number of unack'ed sent Packets
72
        SND_NXT                 dd ? ; next send sequence number to use
2890 hidnplayr 73
        SND_UP                  dd ? ; urgent pointer
2402 hidnplayr 74
        SND_WL1                 dd ? ; window minus one
75
        SND_WL2                 dd ? ;
76
        ISS                     dd ? ; initial send sequence number
77
        SND_WND                 dd ? ; send window
1514 hidnplayr 78
 
79
; receive sequence
2957 hidnplayr 80
        RCV_WND                 dd ? ; receive window
2402 hidnplayr 81
        RCV_NXT                 dd ? ; next receive sequence number to use
2890 hidnplayr 82
        RCV_UP                  dd ? ; urgent pointer
2402 hidnplayr 83
        IRS                     dd ? ; initial receive sequence number
1514 hidnplayr 84
 
85
;---------------------
86
; Additional variables
87
 
88
; receive variables
2402 hidnplayr 89
        RCV_ADV                 dd ?
1514 hidnplayr 90
 
91
; retransmit variables
2402 hidnplayr 92
        SND_MAX                 dd ?
1514 hidnplayr 93
 
94
; congestion control
2402 hidnplayr 95
        SND_CWND                dd ?
96
        SND_SSTHRESH            dd ?
1514 hidnplayr 97
 
98
;----------------------
99
; Transmit timing stuff
2402 hidnplayr 100
        t_idle                  dd ?
101
        t_rtt                   dd ?
102
        t_rtseq                 dd ?
103
        t_srtt                  dd ?
104
        t_rttvar                dd ?
105
        t_rttmin                dd ?
106
        max_sndwnd              dd ?
1514 hidnplayr 107
 
108
;-----------------
109
; Out-of-band data
2402 hidnplayr 110
        t_oobflags              dd ?
111
        t_iobc                  dd ?
112
        t_softerror             dd ?
1514 hidnplayr 113
 
114
 
115
;---------
2924 hidnplayr 116
; RFC 1323                              ; the order of next 4 elements may not change
1514 hidnplayr 117
 
2402 hidnplayr 118
        SND_SCALE               db ?
119
        RCV_SCALE               db ?
120
        requested_s_scale       db ?
121
        request_r_scale         db ?
1514 hidnplayr 122
 
2924 hidnplayr 123
        ts_recent               dd ?    ; a copy of the most-recent valid timestamp from the other end
2402 hidnplayr 124
        ts_recent_age           dd ?
125
        last_ack_sent           dd ?
1519 hidnplayr 126
 
2310 hidnplayr 127
 
1519 hidnplayr 128
;-------
129
; Timers
2955 hidnplayr 130
        timer_retransmission    dd ? ; rexmt
131
        timer_persist           dd ?
132
        timer_keepalive         dd ? ; keepalive/syn timeout
133
        timer_timed_wait        dd ? ; also used as 2msl timer
1519 hidnplayr 134
 
2890 hidnplayr 135
; extra
136
 
2924 hidnplayr 137
        ts_ecr                  dd ? ; timestamp echo reply
2937 hidnplayr 138
        ts_val                  dd ?
139
        temp_bits               db ?
2890 hidnplayr 140
 
2305 hidnplayr 141
ends
1249 hidnplayr 142
 
2402 hidnplayr 143
struct  UDP_SOCKET              IP_SOCKET
1249 hidnplayr 144
 
2995 hidnplayr 145
        LocalPort               dw ? ; network byte order
146
        RemotePort              dw ? ; network byte order
2402 hidnplayr 147
        firstpacket             db ?
1249 hidnplayr 148
 
2305 hidnplayr 149
ends
1249 hidnplayr 150
 
151
 
2402 hidnplayr 152
struct  ICMP_SOCKET             IP_SOCKET
1249 hidnplayr 153
 
2402 hidnplayr 154
        Identifier              dw ?
1514 hidnplayr 155
 
2305 hidnplayr 156
ends
1514 hidnplayr 157
 
158
 
2402 hidnplayr 159
struct  RING_BUFFER
2311 hidnplayr 160
 
2402 hidnplayr 161
        start_ptr               dd ? ; Pointer to start of buffer
162
        end_ptr                 dd ? ; pointer to end of buffer
163
        read_ptr                dd ? ; Read pointer
164
        write_ptr               dd ? ; Write pointer
165
        size                    dd ? ; Number of bytes buffered
2311 hidnplayr 166
 
2305 hidnplayr 167
ends
1514 hidnplayr 168
 
2402 hidnplayr 169
struct  STREAM_SOCKET           TCP_SOCKET
1529 hidnplayr 170
 
2402 hidnplayr 171
        rcv                     RING_BUFFER
172
        snd                     RING_BUFFER
1529 hidnplayr 173
 
2305 hidnplayr 174
ends
1529 hidnplayr 175
 
2402 hidnplayr 176
struct  socket_queue_entry
1529 hidnplayr 177
 
2402 hidnplayr 178
        data_ptr                dd ?
179
        buf_ptr                 dd ?
180
        data_size               dd ?
1529 hidnplayr 181
 
1274 hidnplayr 182
ends
183
 
1514 hidnplayr 184
 
2614 hidnplayr 185
SOCKETBUFFSIZE          = 4096     ; in bytes
1514 hidnplayr 186
 
3251 hidnplayr 187
SOCKET_QUEUE_SIZE       = 10       ; maximum number of incoming packets queued for 1 socket
1514 hidnplayr 188
; the incoming packet queue for sockets is placed in the socket struct itself, at this location from start
2614 hidnplayr 189
SOCKET_QUEUE_LOCATION   = (SOCKETBUFFSIZE - SOCKET_QUEUE_SIZE*sizeof.socket_queue_entry - sizeof.queue)
1249 hidnplayr 190
 
1159 hidnplayr 191
uglobal
2402 hidnplayr 192
        net_sockets     rd 4
193
        last_socket_num dd ?
194
        last_UDP_port   dw ? ; These values give the number of the last used ephemeral port
195
        last_TCP_port   dw ? ;
1159 hidnplayr 196
endg
197
 
198
 
1257 hidnplayr 199
;-----------------------------------------------------------------
1159 hidnplayr 200
;
201
; SOCKET_init
202
;
1257 hidnplayr 203
;-----------------------------------------------------------------
2402 hidnplayr 204
macro   SOCKET_init {
1159 hidnplayr 205
 
2402 hidnplayr 206
        xor     eax, eax
207
        mov     edi, net_sockets
208
        mov     ecx, 5
209
        rep     stosd
1159 hidnplayr 210
 
1529 hidnplayr 211
       @@:
2402 hidnplayr 212
        pseudo_random eax
213
        cmp     ax, MIN_EPHEMERAL_PORT
214
        jb      @r
215
        cmp     ax, MAX_EPHEMERAL_PORT
216
        ja      @r
2995 hidnplayr 217
        xchg    al, ah
2402 hidnplayr 218
        mov     [last_UDP_port], ax
1529 hidnplayr 219
 
220
       @@:
2402 hidnplayr 221
        pseudo_random eax
222
        cmp     ax, MIN_EPHEMERAL_PORT
223
        jb      @r
224
        cmp     ax, MAX_EPHEMERAL_PORT
225
        ja      @r
2995 hidnplayr 226
        xchg    al, ah
2402 hidnplayr 227
        mov     [last_TCP_port], ax
1529 hidnplayr 228
 
229
}
230
 
1257 hidnplayr 231
;-----------------------------------------------------------------
1159 hidnplayr 232
;
233
; Socket API (function 74)
234
;
1257 hidnplayr 235
;-----------------------------------------------------------------
2614 hidnplayr 236
align 4
237
sys_socket:
238
 
239
        cmp     ebx, 255
240
        jz      SOCKET_debug
241
 
242
        cmp     ebx, .number
243
        ja      s_error
244
        jmp     dword [.table + 4*ebx]
245
 
246
  .table:
2402 hidnplayr 247
        dd      SOCKET_open     ; 0
248
        dd      SOCKET_close    ; 1
249
        dd      SOCKET_bind     ; 2
250
        dd      SOCKET_listen   ; 3
251
        dd      SOCKET_connect  ; 4
252
        dd      SOCKET_accept   ; 5
253
        dd      SOCKET_send     ; 6
254
        dd      SOCKET_receive  ; 7
255
        dd      SOCKET_set_opt  ; 8
256
        dd      SOCKET_get_opt  ; 9
3228 hidnplayr 257
        dd      SOCKET_pair     ; 10
2614 hidnplayr 258
  .number = ($ - .table) / 4 - 1
2301 hidnplayr 259
 
1529 hidnplayr 260
s_error:
3251 hidnplayr 261
        DEBUGF  2,"SOCKET: error\n"
2402 hidnplayr 262
        mov     dword [esp+32], -1
1529 hidnplayr 263
 
2402 hidnplayr 264
        ret
1529 hidnplayr 265
 
1257 hidnplayr 266
;-----------------------------------------------------------------
1159 hidnplayr 267
;
268
; SOCKET_open
269
;
270
;  IN:  domain in ecx
271
;       type in edx
1196 hidnplayr 272
;       protocol in esi
1159 hidnplayr 273
;  OUT: eax is socket num, -1 on error
274
;
1257 hidnplayr 275
;-----------------------------------------------------------------
1206 hidnplayr 276
align 4
1514 hidnplayr 277
SOCKET_open:
1159 hidnplayr 278
 
3251 hidnplayr 279
        DEBUGF  2,"SOCKET_open: domain=%u type=%u protocol=%x ", ecx, edx, esi
1159 hidnplayr 280
 
2402 hidnplayr 281
        push    ecx edx esi
282
        call    SOCKET_alloc
283
        pop     esi edx ecx
284
        jz      s_error
1159 hidnplayr 285
 
2402 hidnplayr 286
        mov     [esp+32], edi                   ; return socketnumber
3251 hidnplayr 287
        DEBUGF  2,"socknum=%u\n", edi
1542 hidnplayr 288
 
3257 hidnplayr 289
;        push    edx
290
;        and     edx, SO_NONBLOCK
291
        or      [eax + SOCKET.options], SO_NONBLOCK ;edx
292
;        pop     edx
293
;        and     edx, not SO_NONBLOCK
294
 
2402 hidnplayr 295
        mov     [eax + SOCKET.Domain], ecx
296
        mov     [eax + SOCKET.Type], edx
297
        mov     [eax + SOCKET.Protocol], esi
1159 hidnplayr 298
 
2402 hidnplayr 299
        cmp     ecx, AF_INET4
300
        jne     .no_inet4
1529 hidnplayr 301
 
2402 hidnplayr 302
        cmp     edx, SOCK_DGRAM
303
        je      .udp
1536 hidnplayr 304
 
2402 hidnplayr 305
        cmp     edx, SOCK_STREAM
306
        je      .tcp
1529 hidnplayr 307
 
2402 hidnplayr 308
        cmp     edx, SOCK_RAW
309
        je      .raw
1541 hidnplayr 310
 
1536 hidnplayr 311
  .no_inet4:
2931 hidnplayr 312
        cmp     ecx, AF_PPP
313
        jne     .no_ppp
314
 
315
        cmp     esi, PPP_PROTO_ETHERNET
316
        je      .pppoe
317
 
318
  .no_ppp:
3251 hidnplayr 319
        DEBUGF  2,"Unknown socket family/protocol\n"
2402 hidnplayr 320
        ret
1536 hidnplayr 321
 
1542 hidnplayr 322
align 4
323
  .raw:
2402 hidnplayr 324
        test    esi, esi       ; IP_PROTO_IP
325
        jz      .ip
1529 hidnplayr 326
 
2402 hidnplayr 327
        cmp     esi, IP_PROTO_ICMP
328
        je      .icmp
1529 hidnplayr 329
 
2402 hidnplayr 330
        cmp     esi, IP_PROTO_UDP
331
        je      .udp
1533 hidnplayr 332
 
2402 hidnplayr 333
        cmp     esi, IP_PROTO_TCP
334
        je      .tcp
1536 hidnplayr 335
 
2402 hidnplayr 336
        ret
1159 hidnplayr 337
 
1542 hidnplayr 338
align 4
1536 hidnplayr 339
  .udp:
2402 hidnplayr 340
        mov     [eax + SOCKET.Protocol], IP_PROTO_UDP
341
        mov     [eax + SOCKET.snd_proc], SOCKET_send_udp
342
        mov     [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
343
        ret
1529 hidnplayr 344
 
1542 hidnplayr 345
align 4
346
  .tcp:
2402 hidnplayr 347
        mov     [eax + SOCKET.Protocol], IP_PROTO_TCP
348
        mov     [eax + SOCKET.snd_proc], SOCKET_send_tcp
3228 hidnplayr 349
        mov     [eax + SOCKET.rcv_proc], SOCKET_receive_stream
1838 hidnplayr 350
 
2612 hidnplayr 351
        TCP_init_socket eax
2402 hidnplayr 352
        ret
1529 hidnplayr 353
 
354
 
1543 hidnplayr 355
align 4
356
  .ip:
2402 hidnplayr 357
        mov     [eax + SOCKET.snd_proc], SOCKET_send_ip
358
        mov     [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
359
        ret
1541 hidnplayr 360
 
1542 hidnplayr 361
 
362
align 4
1541 hidnplayr 363
  .icmp:
2402 hidnplayr 364
        mov     [eax + SOCKET.snd_proc], SOCKET_send_icmp
365
        mov     [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
366
        ret
1541 hidnplayr 367
 
2931 hidnplayr 368
align 4
369
  .pppoe:
370
        push    eax
371
        init_queue (eax + SOCKET_QUEUE_LOCATION)        ; Set up data receiving queue
372
        pop     eax
1541 hidnplayr 373
 
2931 hidnplayr 374
        mov     [eax + SOCKET.snd_proc], SOCKET_send_pppoe
375
        mov     [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
376
        ret
1541 hidnplayr 377
 
2931 hidnplayr 378
 
1257 hidnplayr 379
;-----------------------------------------------------------------
1159 hidnplayr 380
;
381
; SOCKET_bind
382
;
383
;  IN:  socket number in ecx
384
;       pointer to sockaddr struct in edx
385
;       length of that struct in esi
386
;  OUT: 0 on success
387
;
1257 hidnplayr 388
;-----------------------------------------------------------------
1206 hidnplayr 389
align 4
1514 hidnplayr 390
SOCKET_bind:
1159 hidnplayr 391
 
3251 hidnplayr 392
        DEBUGF  2,"SOCKET_bind: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi
1159 hidnplayr 393
 
2402 hidnplayr 394
        call    SOCKET_num_to_ptr
395
        jz      s_error
1159 hidnplayr 396
 
2402 hidnplayr 397
        cmp     esi, 2
398
        jb      s_error
1159 hidnplayr 399
 
2402 hidnplayr 400
        cmp     word [edx], AF_INET4
401
        je      .af_inet4
1159 hidnplayr 402
 
3251 hidnplayr 403
        cmp     word [edx], AF_LOCAL
404
        je      .af_local
1249 hidnplayr 405
 
2402 hidnplayr 406
        jmp     s_error
1249 hidnplayr 407
 
3251 hidnplayr 408
  .af_local:
2402 hidnplayr 409
        ; TODO: write code here
1249 hidnplayr 410
 
2402 hidnplayr 411
        mov     dword [esp+32], 0
412
        ret
1249 hidnplayr 413
 
1159 hidnplayr 414
  .af_inet4:
415
 
2402 hidnplayr 416
        cmp     esi, 6
417
        jb      s_error
1159 hidnplayr 418
 
2622 hidnplayr 419
        cmp     [eax + SOCKET.Protocol], IP_PROTO_UDP
420
        je      .udp
1159 hidnplayr 421
 
2622 hidnplayr 422
        cmp     [eax + SOCKET.Protocol], IP_PROTO_TCP
423
        je      .tcp
1159 hidnplayr 424
 
2622 hidnplayr 425
        jmp     s_error
426
 
427
  .tcp:
428
  .udp:
429
 
430
        mov     ebx, [edx + 4]                  ; First, fill in the IP
431
        test    ebx, ebx                        ; If IP is 0, use default
432
        jnz     @f
433
        mov     ebx, [NET_DEFAULT]
434
        mov     ebx, [IP_LIST + 4*ebx]
435
       @@:
436
        mov     [eax + IP_SOCKET.LocalIP], ebx
437
 
2995 hidnplayr 438
        mov     bx, [edx + 2]                   ; Now fill in the local port if it's still available
2622 hidnplayr 439
        call    SOCKET_check_port
440
        jz      s_error                         ; ZF is set by socket_check_port, on error
441
 
2891 hidnplayr 442
        DEBUGF  1,"SOCKET_bind: local ip=%u.%u.%u.%u\n",\
2402 hidnplayr 443
        [eax + IP_SOCKET.LocalIP + 0]:1,[eax + IP_SOCKET.LocalIP + 1]:1,\
444
        [eax + IP_SOCKET.LocalIP + 2]:1,[eax + IP_SOCKET.LocalIP + 3]:1
1159 hidnplayr 445
 
2402 hidnplayr 446
        mov     dword [esp+32], 0
447
        ret
1159 hidnplayr 448
 
449
 
450
 
451
 
1257 hidnplayr 452
;-----------------------------------------------------------------
1159 hidnplayr 453
;
454
; SOCKET_connect
455
;
456
;  IN:  socket number in ecx
457
;       pointer to sockaddr struct in edx
458
;       length of that struct in esi
459
;  OUT: 0 on success
460
;
1257 hidnplayr 461
;-----------------------------------------------------------------
1159 hidnplayr 462
align 4
1514 hidnplayr 463
SOCKET_connect:
1159 hidnplayr 464
 
3251 hidnplayr 465
        DEBUGF  2,"SOCKET_connect: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi
1159 hidnplayr 466
 
2402 hidnplayr 467
        call    SOCKET_num_to_ptr
468
        jz      s_error
1159 hidnplayr 469
 
2402 hidnplayr 470
        cmp     esi, 8
471
        jb      s_error
1159 hidnplayr 472
 
2402 hidnplayr 473
        cmp     word [edx], AF_INET4
474
        je      .af_inet4
1159 hidnplayr 475
 
2402 hidnplayr 476
        jmp     s_error
1159 hidnplayr 477
 
478
  .af_inet4:
2402 hidnplayr 479
        cmp     [eax + IP_SOCKET.LocalIP], 0
480
        jne     @f
481
        push    [IP_LIST]
482
        pop     [eax + IP_SOCKET.LocalIP]
1543 hidnplayr 483
       @@:
1159 hidnplayr 484
 
2402 hidnplayr 485
        cmp     [eax + SOCKET.Protocol], IP_PROTO_UDP
486
        je      .udp
1159 hidnplayr 487
 
2402 hidnplayr 488
        cmp     [eax + SOCKET.Protocol], IP_PROTO_TCP
489
        je      .tcp
1159 hidnplayr 490
 
2402 hidnplayr 491
        cmp     [eax + SOCKET.Protocol], IP_PROTO_IP
492
        je      .ip
1541 hidnplayr 493
 
2402 hidnplayr 494
        cmp     [eax + SOCKET.Protocol], IP_PROTO_ICMP
495
        je      .ip
1542 hidnplayr 496
 
2402 hidnplayr 497
        jmp     s_error
1159 hidnplayr 498
 
1542 hidnplayr 499
align 4
1254 hidnplayr 500
  .udp:
2402 hidnplayr 501
        pusha
502
        lea     ecx, [eax + SOCKET.mutex]
503
        call    mutex_lock
504
        popa
1543 hidnplayr 505
 
2402 hidnplayr 506
        pushw   [edx + 2]
507
        pop     [eax + UDP_SOCKET.RemotePort]
1543 hidnplayr 508
 
2402 hidnplayr 509
        pushd   [edx + 4]
510
        pop     [eax + IP_SOCKET.RemoteIP]
1543 hidnplayr 511
 
2402 hidnplayr 512
        cmp     [eax + UDP_SOCKET.LocalPort], 0
513
        jne     @f
514
        call    SOCKET_find_port
1543 hidnplayr 515
       @@:
516
 
2402 hidnplayr 517
        mov     [eax + UDP_SOCKET.firstpacket], 0
1159 hidnplayr 518
 
2402 hidnplayr 519
        push    eax
520
        init_queue (eax + SOCKET_QUEUE_LOCATION)        ; Set up data receiving queue
521
        pop     eax
1159 hidnplayr 522
 
2402 hidnplayr 523
        lea     ecx, [eax + SOCKET.mutex]
524
        call    mutex_unlock
1159 hidnplayr 525
 
2402 hidnplayr 526
        mov     dword [esp+32], 0
527
        ret
528
 
1542 hidnplayr 529
align 4
1254 hidnplayr 530
  .tcp:
2402 hidnplayr 531
        pusha
532
        lea     ecx, [eax + SOCKET.mutex]
533
        call    mutex_lock
534
        popa
1159 hidnplayr 535
 
2402 hidnplayr 536
        pushw   [edx + 2]
537
        pop     [eax + TCP_SOCKET.RemotePort]
1159 hidnplayr 538
 
2402 hidnplayr 539
        pushd   [edx + 4]
540
        pop     [eax + IP_SOCKET.RemoteIP]
1159 hidnplayr 541
 
2402 hidnplayr 542
        cmp     [eax + TCP_SOCKET.LocalPort], 0
543
        jne     @f
544
        call    SOCKET_find_port
1543 hidnplayr 545
       @@:
1159 hidnplayr 546
 
2402 hidnplayr 547
        mov     [eax + TCP_SOCKET.timer_persist], 0
548
        mov     [eax + TCP_SOCKET.t_state], TCPS_SYN_SENT
2612 hidnplayr 549
 
2402 hidnplayr 550
        push    [TCP_sequence_num]
551
        add     [TCP_sequence_num], 6400
552
        pop     [eax + TCP_SOCKET.ISS]
553
        mov     [eax + TCP_SOCKET.timer_keepalive], TCP_time_keep_init
1519 hidnplayr 554
 
2612 hidnplayr 555
 
2402 hidnplayr 556
        TCP_sendseqinit eax
1529 hidnplayr 557
 
1543 hidnplayr 558
;        mov     [ebx + TCP_SOCKET.timer_retransmission],   ;; todo: create macro to set retransmission timer
1533 hidnplayr 559
 
2402 hidnplayr 560
        mov     ebx, eax
1159 hidnplayr 561
 
2402 hidnplayr 562
        lea     eax, [ebx + STREAM_SOCKET.snd]
563
        call    SOCKET_ring_create
1543 hidnplayr 564
 
2402 hidnplayr 565
        lea     eax, [ebx + STREAM_SOCKET.rcv]
566
        call    SOCKET_ring_create
1543 hidnplayr 567
 
2402 hidnplayr 568
        pusha
2939 hidnplayr 569
        lea     ecx, [ebx + SOCKET.mutex]
2402 hidnplayr 570
        call    mutex_unlock
571
        popa
1733 hidnplayr 572
 
2402 hidnplayr 573
        mov     eax, ebx
574
        call    TCP_output
1733 hidnplayr 575
 
2994 hidnplayr 576
;;; TODO: wait for successfull connection if blocking socket
577
 
2402 hidnplayr 578
        mov     dword [esp+32], 0
579
        ret
1159 hidnplayr 580
 
1542 hidnplayr 581
align 4
582
  .ip:
2402 hidnplayr 583
        pusha
584
        lea     ecx, [eax + SOCKET.mutex]
585
        call    mutex_lock
586
        popa
1543 hidnplayr 587
 
2402 hidnplayr 588
        pushd   [edx + 4]
589
        pop     [eax + IP_SOCKET.RemoteIP]
1159 hidnplayr 590
 
2402 hidnplayr 591
        push    eax
592
        init_queue (eax + SOCKET_QUEUE_LOCATION)        ; Set up data receiving queue
593
        pop     eax
1543 hidnplayr 594
 
2402 hidnplayr 595
        lea     ecx, [eax + SOCKET.mutex]
596
        call    mutex_unlock
1541 hidnplayr 597
 
2402 hidnplayr 598
        mov     dword [esp+32], 0
599
        ret
1541 hidnplayr 600
 
2402 hidnplayr 601
 
1257 hidnplayr 602
;-----------------------------------------------------------------
1159 hidnplayr 603
;
604
; SOCKET_listen
605
;
606
;  IN:  socket number in ecx
607
;       backlog in edx
608
;  OUT: eax is socket num, -1 on error
609
;
1257 hidnplayr 610
;-----------------------------------------------------------------
1206 hidnplayr 611
align 4
1514 hidnplayr 612
SOCKET_listen:
1159 hidnplayr 613
 
3251 hidnplayr 614
        DEBUGF  2,"SOCKET_listen: socknum=%u backlog=%u\n", ecx, edx
1159 hidnplayr 615
 
2402 hidnplayr 616
        call    SOCKET_num_to_ptr
617
        jz      s_error
1159 hidnplayr 618
 
2402 hidnplayr 619
        cmp     [eax + SOCKET.Domain], AF_INET4
620
        jne     s_error
1254 hidnplayr 621
 
2402 hidnplayr 622
        cmp     [eax + SOCKET.Protocol], IP_PROTO_TCP
623
        jne     s_error
1254 hidnplayr 624
 
2402 hidnplayr 625
        cmp     [eax + TCP_SOCKET.LocalPort], 0
626
        je      s_error
1514 hidnplayr 627
 
2402 hidnplayr 628
        cmp     [eax + IP_SOCKET.LocalIP], 0
629
        jne     @f
630
        push    [IP_LIST]
631
        pop     [eax + IP_SOCKET.LocalIP]
1543 hidnplayr 632
       @@:
633
 
2402 hidnplayr 634
        cmp     edx, MAX_backlog
635
        jbe     @f
636
        mov     edx, MAX_backlog
1543 hidnplayr 637
       @@:
1159 hidnplayr 638
 
2402 hidnplayr 639
        mov     [eax + SOCKET.backlog], dx
640
        or      [eax + SOCKET.options], SO_ACCEPTCON
641
        mov     [eax + TCP_SOCKET.t_state], TCPS_LISTEN
2880 hidnplayr 642
        mov     [eax + TCP_SOCKET.timer_keepalive], 0           ; disable keepalive timer
1159 hidnplayr 643
 
2402 hidnplayr 644
        push    eax
645
        init_queue (eax + SOCKET_QUEUE_LOCATION)                ; Set up sockets queue
646
        pop     eax
1543 hidnplayr 647
 
2402 hidnplayr 648
        mov     dword [esp+32], 0
1514 hidnplayr 649
 
2402 hidnplayr 650
        ret
1159 hidnplayr 651
 
652
 
1257 hidnplayr 653
;-----------------------------------------------------------------
1159 hidnplayr 654
;
655
; SOCKET_accept
656
;
657
;  IN:  socket number in ecx
658
;       addr in edx
659
;       addrlen in esi
660
;  OUT: eax is socket num, -1 on error
661
;
1257 hidnplayr 662
;-----------------------------------------------------------------
1206 hidnplayr 663
align 4
1514 hidnplayr 664
SOCKET_accept:
1159 hidnplayr 665
 
3251 hidnplayr 666
        DEBUGF  2,"SOCKET_accept: socknum=%u sockaddr=%x length=%u\n", ecx, edx, esi
1159 hidnplayr 667
 
2402 hidnplayr 668
        call    SOCKET_num_to_ptr
669
        jz      s_error
1159 hidnplayr 670
 
2402 hidnplayr 671
        test    [eax + SOCKET.options], SO_ACCEPTCON
672
        jz      s_error
1543 hidnplayr 673
 
2402 hidnplayr 674
        cmp     [eax + SOCKET.Domain], AF_INET4
675
        jne     s_error
1249 hidnplayr 676
 
2402 hidnplayr 677
        cmp     [eax + SOCKET.Protocol], IP_PROTO_TCP
678
        jne     s_error
1249 hidnplayr 679
 
2994 hidnplayr 680
  .loop:
681
        get_from_queue (eax + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, .block
682
 
683
; Ok, we got a socket ptr
2572 hidnplayr 684
        mov     eax, [esi]
1249 hidnplayr 685
 
3264 hidnplayr 686
; Change thread ID to that of the current thread
2572 hidnplayr 687
        mov     ebx, [TASK_BASE]
688
        mov     ebx, [ebx + TASKDATA.pid]
3264 hidnplayr 689
        mov     [eax + SOCKET.TID], ebx
2572 hidnplayr 690
 
2994 hidnplayr 691
; Convert it to a socket number
2402 hidnplayr 692
        call    SOCKET_ptr_to_num
693
        jz      s_error
2994 hidnplayr 694
; and return it to caller
2402 hidnplayr 695
        mov     [esp+32], eax
696
        ret
1514 hidnplayr 697
 
2994 hidnplayr 698
  .block:
3257 hidnplayr 699
        test    [eax + SOCKET.options], SO_NONBLOCK
700
        jnz     s_error
1159 hidnplayr 701
 
3257 hidnplayr 702
        call    SOCKET_block
703
        jmp     .loop
704
 
1257 hidnplayr 705
;-----------------------------------------------------------------
1159 hidnplayr 706
;
707
; SOCKET_close
708
;
709
;  IN:  socket number in ecx
710
;  OUT: eax is socket num, -1 on error
711
;
1257 hidnplayr 712
;-----------------------------------------------------------------
1206 hidnplayr 713
align 4
1514 hidnplayr 714
SOCKET_close:
1159 hidnplayr 715
 
3251 hidnplayr 716
        DEBUGF  2,"SOCKET_close: socknum=%u\n", ecx
1159 hidnplayr 717
 
2402 hidnplayr 718
        call    SOCKET_num_to_ptr
719
        jz      s_error
1159 hidnplayr 720
 
3264 hidnplayr 721
        mov     dword [esp+32], 0                               ; The socket exists, so we will succeed in closing it.
722
 
723
  .socket:
3267 hidnplayr 724
        or      [eax + SOCKET.options], SO_NONBLOCK             ; Mark the socket as non blocking, we dont want it to block any longer!
725
 
726
        test    [eax + SOCKET.state], SS_BLOCKED                ; Is the socket still in blocked state?
727
        jz      @f
728
        call    SOCKET_notify.unblock                           ; Unblock it.
729
  @@:
730
 
2402 hidnplayr 731
        cmp     [eax + SOCKET.Domain], AF_INET4
3264 hidnplayr 732
        jne     .free
1159 hidnplayr 733
 
2402 hidnplayr 734
        cmp     [eax + SOCKET.Protocol], IP_PROTO_TCP
735
        je      .tcp
1159 hidnplayr 736
 
3264 hidnplayr 737
  .free:
738
        call    SOCKET_free
739
        ret
1159 hidnplayr 740
 
741
  .tcp:
2402 hidnplayr 742
        cmp     [eax + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED    ; state must be LISTEN, SYN_SENT or CLOSED
743
        jb      .free
1318 hidnplayr 744
 
2890 hidnplayr 745
        call    TCP_usrclosed
2891 hidnplayr 746
        call    TCP_output      ;;;; Fixme: is this nescessary??
2994 hidnplayr 747
 
2402 hidnplayr 748
        ret
1159 hidnplayr 749
 
750
 
1257 hidnplayr 751
;-----------------------------------------------------------------
1159 hidnplayr 752
;
753
; SOCKET_receive
754
;
755
;  IN:  socket number in ecx
1249 hidnplayr 756
;       addr to buffer in edx
757
;       length of buffer in esi
1159 hidnplayr 758
;       flags in edi
759
;  OUT: eax is number of bytes copied, -1 on error
760
;
1257 hidnplayr 761
;-----------------------------------------------------------------
1206 hidnplayr 762
align 4
1514 hidnplayr 763
SOCKET_receive:
1159 hidnplayr 764
 
3251 hidnplayr 765
        DEBUGF  2,"SOCKET_receive: socknum=%u bufaddr=%x buflength=%u flags=%x\n", ecx, edx, esi, edi
1514 hidnplayr 766
 
2402 hidnplayr 767
        call    SOCKET_num_to_ptr
768
        jz      s_error
1159 hidnplayr 769
 
2402 hidnplayr 770
        jmp     [eax + SOCKET.rcv_proc]
1533 hidnplayr 771
 
1536 hidnplayr 772
 
773
align 4
1541 hidnplayr 774
SOCKET_receive_dgram:
1536 hidnplayr 775
 
2402 hidnplayr 776
        DEBUGF  1,"SOCKET_receive: DGRAM\n"
1536 hidnplayr 777
 
2402 hidnplayr 778
        mov     ebx, esi
779
        mov     edi, edx                                        ; addr to buffer
1159 hidnplayr 780
 
2994 hidnplayr 781
  .loop:
782
        get_from_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, .block      ; destroys esi and ecx
1536 hidnplayr 783
 
2402 hidnplayr 784
        mov     ecx, [esi + socket_queue_entry.data_size]
2891 hidnplayr 785
        DEBUGF  1,"SOCKET_receive: %u bytes data\n", ecx
1159 hidnplayr 786
 
2402 hidnplayr 787
        cmp     ecx, ebx
788
        ja      .too_small
1514 hidnplayr 789
 
2402 hidnplayr 790
        push    [esi + socket_queue_entry.buf_ptr]              ; save the buffer addr so we can clear it later
791
        mov     esi, [esi + socket_queue_entry.data_ptr]
2891 hidnplayr 792
        DEBUGF  1,"SOCKET_receive: Source buffer=%x real addr=%x\n", [esp], esi
2402 hidnplayr 793
        mov     [esp+32+4], ecx                                 ; return number of bytes copied
1159 hidnplayr 794
 
1514 hidnplayr 795
; copy the data
2402 hidnplayr 796
        shr     ecx, 1
797
        jnc     .nb
798
        movsb
1536 hidnplayr 799
  .nb:
2402 hidnplayr 800
        shr     ecx, 1
801
        jnc     .nw
802
        movsw
1536 hidnplayr 803
  .nw:
2402 hidnplayr 804
        test    ecx, ecx
805
        jz      .nd
806
        rep     movsd
1536 hidnplayr 807
  .nd:
1159 hidnplayr 808
 
2402 hidnplayr 809
        call    kernel_free                                     ; remove the packet
810
        ret
1514 hidnplayr 811
 
1536 hidnplayr 812
  .too_small:
1533 hidnplayr 813
 
3251 hidnplayr 814
        DEBUGF  2,"SOCKET_receive: Buffer too small\n"
2402 hidnplayr 815
        jmp     s_error
1536 hidnplayr 816
 
2994 hidnplayr 817
  .block:
3257 hidnplayr 818
        test    [eax + SOCKET.options], SO_NONBLOCK
819
        jnz     s_error
2994 hidnplayr 820
 
3257 hidnplayr 821
        call    SOCKET_block
822
        jmp     .loop
2994 hidnplayr 823
 
3253 hidnplayr 824
 
1536 hidnplayr 825
align 4
3259 hidnplayr 826
SOCKET_receive_local:
827
 
828
        ; does this socket have a PID yet?
829
        cmp     [eax + SOCKET.PID], 0
830
        jne     @f
831
 
832
        ; Change PID to that of current process
833
        mov     ebx, [TASK_BASE]
834
        mov     ebx, [ebx + TASKDATA.pid]
835
        mov     [eax + SOCKET.PID], ebx
3264 hidnplayr 836
        mov     [eax + SOCKET.TID], ebx         ; currently TID = PID in kolibrios :(
3259 hidnplayr 837
      @@:
838
 
839
        mov     [eax + SOCKET.rcv_proc], SOCKET_receive_stream
840
 
841
align 4
3228 hidnplayr 842
SOCKET_receive_stream:
1536 hidnplayr 843
 
3228 hidnplayr 844
        DEBUGF  1,"SOCKET_receive: STREAM\n"
1536 hidnplayr 845
 
2402 hidnplayr 846
        mov     ecx, esi
847
        mov     edi, edx
2994 hidnplayr 848
        xor     edx, edx
2998 hidnplayr 849
  .loop:
3257 hidnplayr 850
        cmp     [eax + STREAM_SOCKET.rcv + RING_BUFFER.size], 0
2998 hidnplayr 851
        je      .block
3257 hidnplayr 852
        add     eax, STREAM_SOCKET.rcv
2402 hidnplayr 853
        call    SOCKET_ring_read
854
        call    SOCKET_ring_free
1533 hidnplayr 855
 
2402 hidnplayr 856
        mov     [esp+32], ecx                                   ; return number of bytes copied
857
        ret
1159 hidnplayr 858
 
2994 hidnplayr 859
  .block:
3257 hidnplayr 860
        test    [eax + SOCKET.options], SO_NONBLOCK
861
        jnz     s_error
1159 hidnplayr 862
 
3257 hidnplayr 863
        call    SOCKET_block
864
        jmp     .loop
2994 hidnplayr 865
 
3257 hidnplayr 866
 
1257 hidnplayr 867
;-----------------------------------------------------------------
1159 hidnplayr 868
;
869
; SOCKET_send
870
;
871
;
872
;  IN:  socket number in ecx
1206 hidnplayr 873
;       pointer to data in edx
874
;       datalength in esi
1159 hidnplayr 875
;       flags in edi
876
;  OUT: -1 on error
877
;
1257 hidnplayr 878
;-----------------------------------------------------------------
1206 hidnplayr 879
align 4
1514 hidnplayr 880
SOCKET_send:
1159 hidnplayr 881
 
3251 hidnplayr 882
        DEBUGF  2,"SOCKET_send: socknum=%u data ptr=%x length=%u flags=%x\n", ecx, edx, esi, edi
1159 hidnplayr 883
 
2402 hidnplayr 884
        call    SOCKET_num_to_ptr
885
        jz      s_error
1159 hidnplayr 886
 
2402 hidnplayr 887
        mov     ecx, esi
888
        mov     esi, edx
1763 hidnplayr 889
 
2402 hidnplayr 890
        jmp     [eax + SOCKET.snd_proc]
1206 hidnplayr 891
 
892
 
1536 hidnplayr 893
align 4
894
SOCKET_send_udp:
1529 hidnplayr 895
 
2402 hidnplayr 896
        DEBUGF  1,"SOCKET_send: UDP\n"
1159 hidnplayr 897
 
2573 hidnplayr 898
        mov     [esp+32], ecx
2402 hidnplayr 899
        call    UDP_output
2573 hidnplayr 900
        cmp     eax, -1
901
        je      s_error
2402 hidnplayr 902
        ret
1159 hidnplayr 903
 
904
 
1536 hidnplayr 905
align 4
906
SOCKET_send_tcp:
1254 hidnplayr 907
 
2402 hidnplayr 908
        DEBUGF  1,"SOCKET_send: TCP\n"
1254 hidnplayr 909
 
2402 hidnplayr 910
        push    eax
911
        add     eax, STREAM_SOCKET.snd
912
        call    SOCKET_ring_write
913
        pop     eax
1536 hidnplayr 914
 
2621 hidnplayr 915
        mov     [esp+32], ecx
916
 
2402 hidnplayr 917
        call    TCP_output
918
        ret
1159 hidnplayr 919
 
1249 hidnplayr 920
 
1543 hidnplayr 921
align 4
922
SOCKET_send_ip:
1249 hidnplayr 923
 
2891 hidnplayr 924
        DEBUGF  1,"SOCKET_send: IPv4\n"
1543 hidnplayr 925
 
2573 hidnplayr 926
        mov     [esp+32], ecx
2402 hidnplayr 927
        call    IPv4_output_raw
2573 hidnplayr 928
        cmp     eax, -1
929
        je      s_error
2402 hidnplayr 930
        ret
1543 hidnplayr 931
 
2573 hidnplayr 932
 
1541 hidnplayr 933
align 4
934
SOCKET_send_icmp:
1249 hidnplayr 935
 
2402 hidnplayr 936
        DEBUGF  1,"SOCKET_send: ICMP\n"
1541 hidnplayr 937
 
2573 hidnplayr 938
        mov     [esp+32], ecx
2402 hidnplayr 939
        call    ICMP_output_raw
2573 hidnplayr 940
        cmp     eax, -1
941
        je      s_error
2402 hidnplayr 942
        ret
1541 hidnplayr 943
 
944
 
2931 hidnplayr 945
align 4
946
SOCKET_send_pppoe:
1541 hidnplayr 947
 
2931 hidnplayr 948
        DEBUGF  1,"SOCKET_send: PPPoE\n"
1541 hidnplayr 949
 
2931 hidnplayr 950
        mov     [esp+32], ecx
951
        mov     ebx, [eax + SOCKET.device]
952
 
953
        call    PPPoE_discovery_output
954
        cmp     eax, -1
955
        je      s_error
956
        ret
957
 
958
 
959
 
3228 hidnplayr 960
align 4
3251 hidnplayr 961
SOCKET_send_local:
2931 hidnplayr 962
 
3229 hidnplayr 963
        ; does this socket have a PID yet?
964
        cmp     [eax + SOCKET.PID], 0
965
        jne     @f
966
 
967
        ; Change PID to that of current process
968
        mov     ebx, [TASK_BASE]
969
        mov     ebx, [ebx + TASKDATA.pid]
970
        mov     [eax + SOCKET.PID], ebx
3264 hidnplayr 971
        mov     [eax + SOCKET.TID], ebx         ; currently TID = PID in kolibrios :(
3229 hidnplayr 972
      @@:
3259 hidnplayr 973
        mov     [eax + SOCKET.snd_proc], SOCKET_send_local_
3229 hidnplayr 974
 
3259 hidnplayr 975
align 4
976
SOCKET_send_local_:
977
 
978
        DEBUGF  1,"SOCKET_send: LOCAL\n"
979
 
3229 hidnplayr 980
        ; get the other side's socket and check if it still exists
3228 hidnplayr 981
        mov     eax, [eax + SOCKET.device]
982
        call    SOCKET_check
983
        jz      s_error
984
 
3229 hidnplayr 985
        ; allright, shove in the data!
3228 hidnplayr 986
        push    eax
987
        add     eax, STREAM_SOCKET.rcv
988
        call    SOCKET_ring_write
989
        pop     eax
990
 
3229 hidnplayr 991
        ; return the number of written bytes (or errorcode) to application
3228 hidnplayr 992
        mov     [esp+32], ecx
993
 
3229 hidnplayr 994
        ; and notify the other end
3257 hidnplayr 995
        call    SOCKET_notify
3228 hidnplayr 996
 
997
        ret
998
 
999
 
1257 hidnplayr 1000
;-----------------------------------------------------------------
1256 clevermous 1001
;
1257 hidnplayr 1002
; SOCKET_get_options
1256 clevermous 1003
;
1514 hidnplayr 1004
;  IN:  ecx = socket number
1005
;       edx = pointer to the options:
1257 hidnplayr 1006
;               dd      level, optname, optval, optlen
1256 clevermous 1007
;  OUT: -1 on error
1008
;
1009
; At moment, uses only pseudo-optname -2 for get last_ack_number for TCP.
1010
; TODO: find best way to notify that send()'ed data were acknowledged
1831 hidnplayr 1011
; Also pseudo-optname -3 is valid and returns socket state, one of TCPS_*.
1256 clevermous 1012
;
1257 hidnplayr 1013
;-----------------------------------------------------------------
1014
align 4
1514 hidnplayr 1015
SOCKET_get_opt:
1257 hidnplayr 1016
 
3251 hidnplayr 1017
        DEBUGF  2,"SOCKET_get_opt\n"
1514 hidnplayr 1018
 
2402 hidnplayr 1019
        call    SOCKET_num_to_ptr
1020
        jz      s_error
1514 hidnplayr 1021
 
2402 hidnplayr 1022
        cmp     dword [edx], IP_PROTO_TCP
1023
        jne     s_error
1024
        cmp     dword [edx+4], -2
1025
        je      @f
1026
        cmp     dword [edx+4], -3
1027
        jne     s_error
1299 clevermous 1028
@@:
1514 hidnplayr 1029
;        mov     eax, [edx+12]
1030
;        test    eax, eax
1031
;        jz      .fail
1032
;        cmp     dword [eax], 4
1033
;        mov     dword [eax], 4
1034
;        jb      .fail
1035
;        stdcall net_socket_num_to_addr, ecx
1036
;        test    eax, eax
1037
;        jz      .fail
1038
;        ; todo: check that eax is really TCP socket
1039
;        mov     ecx, [eax + TCP_SOCKET.last_ack_number]
1040
;        cmp     dword [edx+4], -2
1041
;        jz      @f
1042
;        mov     ecx, [eax + TCP_SOCKET.state]
1299 clevermous 1043
@@:
2402 hidnplayr 1044
        mov     eax, [edx+8]
1045
        test    eax, eax
1046
        jz      @f
1047
        mov     [eax], ecx
1256 clevermous 1048
@@:
2402 hidnplayr 1049
        mov     dword [esp+32], 0
1050
        ret
1159 hidnplayr 1051
 
1052
 
1529 hidnplayr 1053
 
2731 hidnplayr 1054
;-----------------------------------------------------------------
1055
;
1056
; SOCKET_set_options
1057
;
1058
;  IN:  ecx = socket number
1059
;       edx = pointer to the options:
2877 hidnplayr 1060
;               dd      level, optname, optlen, optval
2731 hidnplayr 1061
;  OUT: -1 on error
1062
;
1063
;-----------------------------------------------------------------
1542 hidnplayr 1064
align 4
1065
SOCKET_set_opt:
1066
 
3251 hidnplayr 1067
        DEBUGF  2,"SOCKET_set_opt\n"
2731 hidnplayr 1068
 
1069
        call    SOCKET_num_to_ptr
1070
        jz      s_error
1071
 
2877 hidnplayr 1072
        cmp     dword [edx], SOL_SOCKET
1073
        jne     s_error
2731 hidnplayr 1074
 
2877 hidnplayr 1075
        cmp     dword [edx+4], SO_BINDTODEVICE
1076
        je      .bind
2731 hidnplayr 1077
 
2996 hidnplayr 1078
        cmp     dword [edx+4], SO_BLOCK
1079
        je      .block
1080
 
2877 hidnplayr 1081
        jmp     s_error
1082
 
1083
  .bind:
1084
        cmp     dword [edx+8], 0
1085
        je      .unbind
1086
 
1087
        movzx   edx, byte [edx + 9]
1088
        cmp     edx, MAX_NET_DEVICES
1089
        ja      s_error
1090
 
1091
        mov     edx, [NET_DRV_LIST + 4*edx]
1092
        test    edx, edx
1093
        jz      s_error
1094
        mov     [eax + SOCKET.device], edx
1095
 
2891 hidnplayr 1096
        DEBUGF  1,"SOCKET_set_opt: Bound socket %x to device %x\n",eax, edx
2877 hidnplayr 1097
 
1098
        mov     dword [esp+32], 0       ; success!
2402 hidnplayr 1099
        ret
1542 hidnplayr 1100
 
2877 hidnplayr 1101
  .unbind:
1102
        mov     [eax + SOCKET.device], 0
1542 hidnplayr 1103
 
2877 hidnplayr 1104
        mov     dword [esp+32], 0       ; success!
1105
        ret
1542 hidnplayr 1106
 
2996 hidnplayr 1107
  .block:
1108
        cmp     dword [edx+8], 0
1109
        je      .unblock
2877 hidnplayr 1110
 
3257 hidnplayr 1111
        and     [eax + SOCKET.options], not SO_NONBLOCK
2877 hidnplayr 1112
 
2996 hidnplayr 1113
        mov     dword [esp+32], 0       ; success!
1114
        ret
1115
 
1116
  .unblock:
3257 hidnplayr 1117
        or      [eax + SOCKET.options], SO_NONBLOCK
2996 hidnplayr 1118
 
1119
        mov     dword [esp+32], 0       ; success!
1120
        ret
1121
 
1122
 
1123
 
3228 hidnplayr 1124
;-----------------------------------------------------------------
1125
;
1126
; SOCKET_pair
1127
;
3251 hidnplayr 1128
; Allocates a pair of linked LOCAL domain sockets
3228 hidnplayr 1129
;
1130
; IN: /
1131
; OUT: eax is socket1 num, -1 on error
1132
;      ebx is socket2 num
1133
;
1134
;-----------------------------------------------------------------
1135
align 4
1136
SOCKET_pair:
2996 hidnplayr 1137
 
3251 hidnplayr 1138
        DEBUGF  2,"SOCKET_pair\n"
2996 hidnplayr 1139
 
3228 hidnplayr 1140
        call    SOCKET_alloc
1141
        jz      s_error
1142
        mov     [esp+32], edi   ; application's eax
1143
 
3251 hidnplayr 1144
        mov     [eax + SOCKET.Domain], AF_LOCAL
3228 hidnplayr 1145
        mov     [eax + SOCKET.Type], SOCK_STREAM
1146
        mov     [eax + SOCKET.Protocol], 0              ;;; CHECKME
3251 hidnplayr 1147
        mov     [eax + SOCKET.snd_proc], SOCKET_send_local
3259 hidnplayr 1148
        mov     [eax + SOCKET.rcv_proc], SOCKET_receive_local
3261 hidnplayr 1149
        mov     [eax + SOCKET.PID], 0
3228 hidnplayr 1150
        mov     ebx, eax
1151
 
1152
        call    SOCKET_alloc
1153
        jz      .error
1154
        mov     [esp+24], edi   ; application's ebx
1155
 
3251 hidnplayr 1156
        mov     [eax + SOCKET.Domain], AF_LOCAL
3228 hidnplayr 1157
        mov     [eax + SOCKET.Type], SOCK_STREAM
1158
        mov     [eax + SOCKET.Protocol], 0              ;;; CHECKME
3251 hidnplayr 1159
        mov     [eax + SOCKET.snd_proc], SOCKET_send_local
3259 hidnplayr 1160
        mov     [eax + SOCKET.rcv_proc], SOCKET_receive_local
3261 hidnplayr 1161
        mov     [eax + SOCKET.PID], 0
3228 hidnplayr 1162
 
1163
        ; Link the two sockets to eachother
1164
        mov     [eax + SOCKET.device], ebx
1165
        mov     [ebx + SOCKET.device], eax
1166
 
1167
        lea     eax, [eax + STREAM_SOCKET.rcv]
1168
        call    SOCKET_ring_create
1169
 
1170
        lea     eax, [ebx + STREAM_SOCKET.rcv]
1171
        call    SOCKET_ring_create
1172
        pop     eax
1173
 
1174
        ret
1175
 
1176
  .error:
1177
        mov     eax, ebx
1178
        call    SOCKET_free
1179
        jmp     s_error
1180
 
1181
 
1182
 
1257 hidnplayr 1183
;-----------------------------------------------------------------
1206 hidnplayr 1184
;
1529 hidnplayr 1185
; SOCKET_debug
1186
;
1187
;  Copies socket variables to application buffer
1188
;
1189
;  IN:  ecx = socket number
1190
;       edx = pointer to buffer
1191
;
1192
;  OUT: -1 on error
1193
;-----------------------------------------------------------------
1194
align 4
1195
SOCKET_debug:
1196
 
3251 hidnplayr 1197
        DEBUGF  1,"SOCKET_debug\n"
1529 hidnplayr 1198
 
3146 hidnplayr 1199
        mov     edi, edx
1200
 
1201
        test    ecx, ecx
1202
        jz      .returnall
1203
 
2402 hidnplayr 1204
        call    SOCKET_num_to_ptr
1205
        jz      s_error
1529 hidnplayr 1206
 
2402 hidnplayr 1207
        mov     esi, eax
1208
        mov     ecx, SOCKETBUFFSIZE/4
1209
        rep     movsd
1529 hidnplayr 1210
 
2402 hidnplayr 1211
        mov     dword [esp+32], 0
1212
        ret
1529 hidnplayr 1213
 
3146 hidnplayr 1214
  .returnall:
1215
        mov     ebx, net_sockets
1216
  .next_socket:
1217
        mov     ebx, [ebx + SOCKET.NextPtr]
1218
        test    ebx, ebx
1219
        jz      .done
1220
        mov     eax, [ebx + SOCKET.Number]
1221
        stosd
1222
        jmp     .next_socket
1223
  .done:
1224
        xor     eax, eax
1225
        stosd
1529 hidnplayr 1226
 
3146 hidnplayr 1227
        mov     dword [esp+32], 0
1228
        ret
1229
 
1230
 
1529 hidnplayr 1231
;-----------------------------------------------------------------
1232
;
1514 hidnplayr 1233
; SOCKET_find_port
1206 hidnplayr 1234
;
1514 hidnplayr 1235
; Fills in the local port number for TCP and UDP sockets
1236
; This procedure always works because the number of sockets is
1237
; limited to a smaller number then the number of possible ports
1206 hidnplayr 1238
;
1514 hidnplayr 1239
;  IN:  eax = socket pointer
1240
;  OUT: /
1206 hidnplayr 1241
;
1257 hidnplayr 1242
;-----------------------------------------------------------------
1206 hidnplayr 1243
align 4
1514 hidnplayr 1244
SOCKET_find_port:
1159 hidnplayr 1245
 
3251 hidnplayr 1246
        DEBUGF  2,"SOCKET_find_port\n"
1159 hidnplayr 1247
 
2402 hidnplayr 1248
        push    ebx esi ecx
1514 hidnplayr 1249
 
2402 hidnplayr 1250
        cmp     [eax + SOCKET.Protocol], IP_PROTO_UDP
1251
        je      .udp
1159 hidnplayr 1252
 
2402 hidnplayr 1253
        cmp     [eax + SOCKET.Protocol], IP_PROTO_TCP
1254
        je      .tcp
1159 hidnplayr 1255
 
2402 hidnplayr 1256
        pop     ecx esi ebx
1257
        ret
1514 hidnplayr 1258
 
1206 hidnplayr 1259
  .udp:
2402 hidnplayr 1260
        mov     bx, [last_UDP_port]
1261
        call    .findit
1262
        mov     [last_UDP_port], bx
1206 hidnplayr 1263
 
2995 hidnplayr 1264
        pop     ecx esi ebx
1265
        ret
1266
 
1206 hidnplayr 1267
  .tcp:
2402 hidnplayr 1268
        mov     bx, [last_TCP_port]
1269
        call    .findit
1270
        mov     [last_TCP_port], bx
1206 hidnplayr 1271
 
2995 hidnplayr 1272
        pop     ecx esi ebx
1273
        ret
1206 hidnplayr 1274
 
2995 hidnplayr 1275
 
1514 hidnplayr 1276
  .restart:
2995 hidnplayr 1277
        mov     bx, MIN_EPHEMERAL_PORT_N
1514 hidnplayr 1278
  .findit:
2995 hidnplayr 1279
        cmp     bx, MAX_EPHEMERAL_PORT_N
1280
        je      .restart
1206 hidnplayr 1281
 
2995 hidnplayr 1282
        add     bh, 1
1283
        adc     bl, 0
1206 hidnplayr 1284
 
2402 hidnplayr 1285
        call    SOCKET_check_port
1286
        jz      .findit
1287
        ret
1206 hidnplayr 1288
 
1257 hidnplayr 1289
 
1290
 
1291
;-----------------------------------------------------------------
1206 hidnplayr 1292
;
1542 hidnplayr 1293
; SOCKET_check_port (to be used with AF_INET only!)
1206 hidnplayr 1294
;
1514 hidnplayr 1295
; Checks if a local port number is unused
1296
; If the proposed port number is unused, it is filled in in the socket structure
1206 hidnplayr 1297
;
1514 hidnplayr 1298
;  IN:  eax = socket ptr (to find out if its a TCP/UDP socket)
2995 hidnplayr 1299
;        bx = proposed socket number (network byte order)
1206 hidnplayr 1300
;
2995 hidnplayr 1301
;  OUT:  ZF = set on error
1514 hidnplayr 1302
;
1257 hidnplayr 1303
;-----------------------------------------------------------------
1206 hidnplayr 1304
align 4
1514 hidnplayr 1305
SOCKET_check_port:
1306
 
3251 hidnplayr 1307
        DEBUGF  2,"SOCKET_check_port: "
1514 hidnplayr 1308
 
2402 hidnplayr 1309
        mov     ecx, [eax + SOCKET.Protocol]
2622 hidnplayr 1310
        mov     edx, [eax + IP_SOCKET.LocalIP]
2402 hidnplayr 1311
        mov     esi, net_sockets
1206 hidnplayr 1312
 
1313
  .next_socket:
2402 hidnplayr 1314
        mov     esi, [esi + SOCKET.NextPtr]
1315
        or      esi, esi
1316
        jz      .port_ok
1206 hidnplayr 1317
 
2402 hidnplayr 1318
        cmp     [esi + SOCKET.Protocol], ecx
1319
        jne     .next_socket
1206 hidnplayr 1320
 
2622 hidnplayr 1321
        cmp     [esi + IP_SOCKET.LocalIP], edx
1322
        jne     .next_socket
1323
 
2402 hidnplayr 1324
        cmp     [esi + UDP_SOCKET.LocalPort], bx
1325
        jne     .next_socket
1206 hidnplayr 1326
 
3251 hidnplayr 1327
        DEBUGF  2,"local port %x already in use\n", bx  ; FIXME: find a way to print big endian values with debugf
2402 hidnplayr 1328
        ret
1206 hidnplayr 1329
 
1330
  .port_ok:
3251 hidnplayr 1331
        DEBUGF  2,"local port %x is free\n", bx         ; FIXME: find a way to print big endian values with debugf
2402 hidnplayr 1332
        mov     [eax + UDP_SOCKET.LocalPort], bx
2995 hidnplayr 1333
        or      bx, bx                                  ; clear the zero-flag
2402 hidnplayr 1334
        ret
1206 hidnplayr 1335
 
1336
 
1257 hidnplayr 1337
 
1338
;-----------------------------------------------------------------
1206 hidnplayr 1339
;
1514 hidnplayr 1340
; SOCKET_input
1206 hidnplayr 1341
;
1536 hidnplayr 1342
; Updates a (stateless) socket with received data
1206 hidnplayr 1343
;
1514 hidnplayr 1344
; Note: the mutex should already be set !
1206 hidnplayr 1345
;
1249 hidnplayr 1346
;  IN:  eax = socket ptr
1514 hidnplayr 1347
;       ecx = data size
1348
;       esi = ptr to data
1349
;       [esp] = ptr to buf
1350
;       [esp + 4] = buf size
1249 hidnplayr 1351
;
1514 hidnplayr 1352
;  OUT: /
1206 hidnplayr 1353
;
1257 hidnplayr 1354
;-----------------------------------------------------------------
1206 hidnplayr 1355
align 4
1514 hidnplayr 1356
SOCKET_input:
1206 hidnplayr 1357
 
3251 hidnplayr 1358
        DEBUGF  2,"SOCKET_input: socket=%x, data=%x size=%u\n", eax, esi, ecx
1206 hidnplayr 1359
 
2402 hidnplayr 1360
        mov     [esp+4], ecx
1361
        push    esi
1362
        mov     esi, esp
1514 hidnplayr 1363
 
2402 hidnplayr 1364
        add_to_queue (eax + SOCKET_QUEUE_LOCATION), SOCKET_QUEUE_SIZE, sizeof.socket_queue_entry, SOCKET_input.full
1514 hidnplayr 1365
 
3251 hidnplayr 1366
        DEBUGF  1,"SOCKET_input: success\n"
2402 hidnplayr 1367
        add     esp, sizeof.socket_queue_entry
1206 hidnplayr 1368
 
2402 hidnplayr 1369
        pusha
1370
        lea     ecx, [eax + SOCKET.mutex]
1371
        call    mutex_unlock
1372
        popa
1373
 
3257 hidnplayr 1374
        jmp     SOCKET_notify
2402 hidnplayr 1375
 
1514 hidnplayr 1376
  .full:
2402 hidnplayr 1377
        DEBUGF  2,"SOCKET_input: socket %x is full!\n", eax
1206 hidnplayr 1378
 
2402 hidnplayr 1379
        pusha
1380
        lea     ecx, [eax + SOCKET.mutex]
1381
        call    mutex_unlock
1382
        popa
1514 hidnplayr 1383
 
2402 hidnplayr 1384
        call    kernel_free
1385
        add     esp, 8
1533 hidnplayr 1386
 
2402 hidnplayr 1387
        ret
1388
 
1389
 
1533 hidnplayr 1390
;--------------------------
1391
;
1392
; eax = ptr to ring struct (just a buffer of the right size)
1393
;
1394
align 4
1395
SOCKET_ring_create:
1396
 
2402 hidnplayr 1397
        push    esi
1398
        mov     esi, eax
1543 hidnplayr 1399
 
2402 hidnplayr 1400
        push    edx
1401
        stdcall create_ring_buffer, SOCKET_MAXDATA, PG_SW
1402
        pop     edx
1533 hidnplayr 1403
 
2402 hidnplayr 1404
        DEBUGF  1,"SOCKET_ring_created: %x\n", eax
1405
        mov     [esi + RING_BUFFER.start_ptr], eax
1406
        mov     [esi + RING_BUFFER.write_ptr], eax
1407
        mov     [esi + RING_BUFFER.read_ptr], eax
1408
        mov     [esi + RING_BUFFER.size], 0
2888 hidnplayr 1409
        add     eax, SOCKET_MAXDATA
2402 hidnplayr 1410
        mov     [esi + RING_BUFFER.end_ptr], eax
1411
        mov     eax, esi
1412
        pop     esi
1533 hidnplayr 1413
 
2402 hidnplayr 1414
        ret
1533 hidnplayr 1415
 
1514 hidnplayr 1416
;-----------------------------------------------------------------
1417
;
1533 hidnplayr 1418
; SOCKET_ring_write
1529 hidnplayr 1419
;
1533 hidnplayr 1420
; Adds data to a stream socket, and updates write pointer and size
1529 hidnplayr 1421
;
1422
;  IN:  eax = ptr to ring struct
1423
;       ecx = data size
1424
;       esi = ptr to data
1425
;
1533 hidnplayr 1426
;  OUT: ecx = number of bytes stored
1529 hidnplayr 1427
;
1428
;-----------------------------------------------------------------
1429
align 4
1533 hidnplayr 1430
SOCKET_ring_write:
1529 hidnplayr 1431
 
2402 hidnplayr 1432
        DEBUGF  1,"SOCKET_ring_write: ringbuff=%x ptr=%x size=%u\n", eax, esi, ecx
1529 hidnplayr 1433
 
2402 hidnplayr 1434
        add     [eax + RING_BUFFER.size], ecx
2573 hidnplayr 1435
        jc      .way_too_large
2402 hidnplayr 1436
        cmp     [eax + RING_BUFFER.size], SOCKET_MAXDATA
1437
        ja      .too_large
1529 hidnplayr 1438
 
1439
  .copy:
2402 hidnplayr 1440
        mov     edi, [eax + RING_BUFFER.write_ptr]
1441
        DEBUGF  2,"SOCKET_ring_write: %u bytes from %x to %x\n", ecx, esi, edi
1529 hidnplayr 1442
 
2402 hidnplayr 1443
        push    ecx
1444
        shr     ecx, 1
1445
        jnc     .nb
1446
        movsb
1536 hidnplayr 1447
  .nb:
2402 hidnplayr 1448
        shr     ecx, 1
1449
        jnc     .nw
1450
        movsw
1536 hidnplayr 1451
  .nw:
2402 hidnplayr 1452
        test    ecx, ecx
1453
        jz      .nd
1454
        rep     movsd
1536 hidnplayr 1455
  .nd:
2402 hidnplayr 1456
        pop     ecx
1529 hidnplayr 1457
 
2402 hidnplayr 1458
        cmp     edi, [eax + RING_BUFFER.end_ptr]
1459
        jae     .wrap
1460
        mov     [eax + RING_BUFFER.write_ptr], edi
1533 hidnplayr 1461
 
2402 hidnplayr 1462
        ret
1529 hidnplayr 1463
 
1533 hidnplayr 1464
  .wrap:
2402 hidnplayr 1465
        sub     edi, SOCKET_MAXDATA
1466
        mov     [eax + RING_BUFFER.write_ptr], edi
1533 hidnplayr 1467
 
2402 hidnplayr 1468
        ret
1533 hidnplayr 1469
 
2404 hidnplayr 1470
  .too_large:                                                           ; update size, we will fill buffer completely
1471
        sub     [eax + RING_BUFFER.size], SOCKET_MAXDATA
2402 hidnplayr 1472
        sub     ecx, [eax + RING_BUFFER.size]
2404 hidnplayr 1473
        mov     [eax + RING_BUFFER.size], SOCKET_MAXDATA
2573 hidnplayr 1474
        ja      .copy
1529 hidnplayr 1475
 
2573 hidnplayr 1476
  .full:
2402 hidnplayr 1477
        DEBUGF  2,"SOCKET_ring_write: ring buffer is full!\n"
1478
        xor     ecx, ecx
1479
        ret
1529 hidnplayr 1480
 
2573 hidnplayr 1481
  .way_too_large:
1482
        sub     [eax + RING_BUFFER.size], ecx
1483
        mov     ecx, SOCKET_MAXDATA
1484
        sub     ecx, [eax + RING_BUFFER.size]
1485
        ja      .copy
1486
        jmp     .full
1529 hidnplayr 1487
 
2573 hidnplayr 1488
 
1489
 
1529 hidnplayr 1490
;-----------------------------------------------------------------
1491
;
1492
; SOCKET_ring_read
1493
;
2893 hidnplayr 1494
;  IN:  eax = ring struct ptr
1495
;       ecx = bytes to read
1496
;       edx = offset
2994 hidnplayr 1497
;       edi = ptr to buffer start
1529 hidnplayr 1498
;
2994 hidnplayr 1499
;  OUT: eax = unchanged
1500
;       ecx = number of bytes read (0 on error)
1501
;       edx = destroyed
1502
;       esi = destroyed
1503
;       edi = ptr to buffer end
1529 hidnplayr 1504
;
1505
;-----------------------------------------------------------------
1506
align 4
1507
SOCKET_ring_read:
1508
 
2893 hidnplayr 1509
        DEBUGF  1,"SOCKET_ring_read: ringbuff=%x ptr=%x size=%u offset=%x\n", eax, edi, ecx, edx
1529 hidnplayr 1510
 
2893 hidnplayr 1511
        mov     esi, [eax + RING_BUFFER.read_ptr]
1512
        add     esi, edx                                        ; esi = start_ptr + offset
1513
 
1514
        neg     edx
1515
        add     edx, [eax + RING_BUFFER.size]                   ; edx = snd.size - offset
1516
        jle     .no_data_at_all
1517
 
1518
        cmp     ecx, edx
2402 hidnplayr 1519
        ja      .less_data
1529 hidnplayr 1520
 
1521
  .copy:
2402 hidnplayr 1522
        DEBUGF  2,"SOCKET_ring_read: %u bytes from %x to %x\n", ecx, esi, edi
1523
        push    ecx
1524
        shr     ecx, 1
1525
        jnc     .nb
1526
        movsb
1536 hidnplayr 1527
  .nb:
2402 hidnplayr 1528
        shr     ecx, 1
1529
        jnc     .nw
1530
        movsw
1536 hidnplayr 1531
  .nw:
2402 hidnplayr 1532
        test    ecx, ecx
1533
        jz      .nd
1534
        rep     movsd
1536 hidnplayr 1535
  .nd:
2402 hidnplayr 1536
        pop     ecx
2893 hidnplayr 1537
        ret
1529 hidnplayr 1538
 
1830 hidnplayr 1539
  .no_data_at_all:
2894 hidnplayr 1540
        DEBUGF  1,"SOCKET_ring_read: no data at all!\n"
2993 hidnplayr 1541
        xor     ecx, ecx
2402 hidnplayr 1542
        ret
1529 hidnplayr 1543
 
1533 hidnplayr 1544
  .less_data:
2893 hidnplayr 1545
        mov     ecx, edx
2402 hidnplayr 1546
        jmp     .copy
1529 hidnplayr 1547
 
1548
 
1549
;-----------------------------------------------------------------
1550
;
1551
; SOCKET_ring_free
1552
;
1553
; Free's some bytes from the ringbuffer
1554
;
1555
;  IN:  eax = ptr to ring struct
1556
;       ecx = data size
1557
;
1558
;  OUT: ecx = number of bytes free-ed
1559
;
1560
;-----------------------------------------------------------------
1561
align 4
1562
SOCKET_ring_free:
1563
 
2402 hidnplayr 1564
        DEBUGF  1,"SOCKET_ring_free: %u bytes from ring %x\n", ecx, eax
1529 hidnplayr 1565
 
2402 hidnplayr 1566
        sub     [eax + RING_BUFFER.size], ecx
2888 hidnplayr 1567
        jb      .error
2402 hidnplayr 1568
        add     [eax + RING_BUFFER.read_ptr], ecx
1529 hidnplayr 1569
 
2402 hidnplayr 1570
        mov     edx, [eax + RING_BUFFER.end_ptr]
1571
        cmp     [eax + RING_BUFFER.read_ptr], edx
1572
        jb      @f
1573
        sub     [eax + RING_BUFFER.read_ptr], SOCKET_MAXDATA
1529 hidnplayr 1574
       @@:
2402 hidnplayr 1575
        ret
1529 hidnplayr 1576
 
2888 hidnplayr 1577
  .error:       ; we could free all available bytes, but that would be stupid, i guess..
1578
        DEBUGF  1,"SOCKET_ring_free: buffer=%x error!\n", eax
2402 hidnplayr 1579
        add     [eax + RING_BUFFER.size], ecx
1580
        xor     ecx, ecx
1581
        ret
1529 hidnplayr 1582
 
1583
 
1584
;-----------------------------------------------------------------
1585
;
3257 hidnplayr 1586
; SOCKET_block
1514 hidnplayr 1587
;
3257 hidnplayr 1588
; Suspends the thread attached to a socket
1589
;
1590
;  IN:  eax = socket ptr
1591
;  OUT: /
1592
;
1593
;-----------------------------------------------------------------
1594
align 4
1595
SOCKET_block:
1596
 
1597
        DEBUGF  1,"SOCKET_block: %x\n", eax
1598
 
1599
        pushf
1600
        cli
1601
 
1602
        ; Set the 'socket is blocked' flag
1603
        or      [eax + SOCKET.state], SS_BLOCKED
1604
 
1605
        ; Suspend the thread
1606
        push    edx
1607
        mov     edx, [TASK_BASE]
1608
        mov     [edx + TASKDATA.state], 1               ; Suspended
3264 hidnplayr 1609
 
1610
        ; Remember the thread ID so we can wake it up again
1611
        mov     edx, [edx + TASKDATA.pid]
1612
        DEBUGF  1,"SOCKET_block: suspending thread: %u\n", edx
1613
        mov     [eax + SOCKET.TID], edx
3257 hidnplayr 1614
        pop     edx
1615
 
1616
        call    change_task
1617
        popf
1618
 
1619
        DEBUGF  1,"SOCKET_block: continueing\n"
1620
 
1621
        ret
1622
 
1623
 
1624
;-----------------------------------------------------------------
1625
;
1626
; SOCKET_notify
1627
;
1514 hidnplayr 1628
; notify's the owner of a socket that something happened
1629
;
1630
;  IN:  eax = socket ptr
1631
;  OUT: /
1632
;
1633
;-----------------------------------------------------------------
1634
align 4
3257 hidnplayr 1635
SOCKET_notify:
1514 hidnplayr 1636
 
3257 hidnplayr 1637
        DEBUGF  1,"SOCKET_notify: %x\n", eax
1514 hidnplayr 1638
 
2402 hidnplayr 1639
        call    SOCKET_check
1640
        jz      .error
1514 hidnplayr 1641
 
3257 hidnplayr 1642
        test    [eax + SOCKET.state], SS_BLOCKED
1643
        jnz     .unblock
1644
 
1645
        test    [eax + SOCKET.options], SO_NONBLOCK
1646
        jz      .error
1647
 
2402 hidnplayr 1648
        push    eax ecx esi
1514 hidnplayr 1649
 
3257 hidnplayr 1650
; socket exists and is of non blocking type.
1651
; We'll try to flag an event to the thread
1514 hidnplayr 1652
 
3264 hidnplayr 1653
        mov     eax, [eax + SOCKET.TID]
2629 hidnplayr 1654
        test    eax, eax
3257 hidnplayr 1655
        jz      .done
2402 hidnplayr 1656
        mov     ecx, 1
1657
        mov     esi, TASK_DATA + TASKDATA.pid
1206 hidnplayr 1658
 
3257 hidnplayr 1659
  .next_pid:
2402 hidnplayr 1660
        cmp     [esi], eax
1661
        je      .found_pid
1662
        inc     ecx
1663
        add     esi, 0x20
1664
        cmp     ecx, [TASK_COUNT]
1665
        jbe     .next_pid
1514 hidnplayr 1666
; PID not found, TODO: close socket!
3257 hidnplayr 1667
        jmp     .done
1514 hidnplayr 1668
 
3257 hidnplayr 1669
  .found_pid:
2402 hidnplayr 1670
        shl     ecx, 8
1671
        or      [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK
3257 hidnplayr 1672
        mov     [check_idle_semaphore], 200                             ; What does this mean??
1206 hidnplayr 1673
 
3257 hidnplayr 1674
        DEBUGF  1,"SOCKET_notify: Raised a network event!\n"
1514 hidnplayr 1675
 
3257 hidnplayr 1676
        jmp     .done
1677
 
1678
  .unblock:
1679
        push    eax ecx esi
1680
        ; Clear the 'socket is blocked' flag
1681
        and     [eax + SOCKET.state], not SS_BLOCKED
1682
 
1683
        ; Find the thread's TASK_DATA
3264 hidnplayr 1684
        mov     eax, [eax + SOCKET.TID]
3257 hidnplayr 1685
        test    eax, eax
1686
        jz      .error
1687
        xor     ecx, ecx
1688
        inc     ecx
1689
        mov     esi, TASK_DATA
1690
  .next:
1691
        cmp     [esi + TASKDATA.pid], eax
1692
        je      .found
1693
        inc     ecx
1694
        add     esi, 0x20
1695
        cmp     ecx, [TASK_COUNT]
1696
        jbe     .next
1697
        jmp     .error
1698
  .found:
1699
 
1700
        ; Run the thread
1701
        mov     [esi + TASKDATA.state], 0       ; Running
1702
        DEBUGF  1,"SOCKET_notify: Unblocked socket!\n"
1703
 
1704
  .done:
2402 hidnplayr 1705
        pop     esi ecx eax
1536 hidnplayr 1706
 
1514 hidnplayr 1707
  .error:
2402 hidnplayr 1708
        ret
1206 hidnplayr 1709
 
1710
 
1514 hidnplayr 1711
;--------------------------------------------------------------------
1712
;
1713
; SOCKET_alloc
1714
;
1159 hidnplayr 1715
; Allocate memory for socket data and put new socket into the list
1716
; Newly created socket is initialized with calling PID and number and
1717
; put into beginning of list (which is a fastest way).
1718
;
1514 hidnplayr 1719
; IN:  /
1720
; OUT: eax = 0 on error, socket ptr otherwise
1721
;      edi = socket number
1722
;       ZF = cleared on error
1159 hidnplayr 1723
;
1514 hidnplayr 1724
;--------------------------------------------------------------------
1725
align 4
1726
SOCKET_alloc:
1727
 
2402 hidnplayr 1728
        push    ebx
1514 hidnplayr 1729
 
2402 hidnplayr 1730
        stdcall kernel_alloc, SOCKETBUFFSIZE
1731
        DEBUGF  1, "SOCKET_alloc: ptr=%x\n", eax
1732
        or      eax, eax
1733
        jz      .exit
1159 hidnplayr 1734
 
1514 hidnplayr 1735
; zero-initialize allocated memory
2402 hidnplayr 1736
        push    eax
1737
        mov     edi, eax
1738
        mov     ecx, SOCKETBUFFSIZE / 4
1739
        xor     eax, eax
1740
        rep     stosd
1741
        pop     eax
1159 hidnplayr 1742
 
1536 hidnplayr 1743
; set send-and receive procedures to return -1
2402 hidnplayr 1744
        mov     [eax + SOCKET.snd_proc], s_error
1745
        mov     [eax + SOCKET.rcv_proc], s_error
1536 hidnplayr 1746
 
1514 hidnplayr 1747
; find first free socket number and use it
2402 hidnplayr 1748
        mov     edi, [last_socket_num]
1159 hidnplayr 1749
  .next_socket_number:
2402 hidnplayr 1750
        inc     edi
1751
        jz      .next_socket_number     ; avoid socket nr 0
1752
        cmp     edi, -1
1753
        je      .next_socket_number     ; avoid socket nr -1
1754
        mov     ebx, net_sockets
1159 hidnplayr 1755
  .next_socket:
2402 hidnplayr 1756
        mov     ebx, [ebx + SOCKET.NextPtr]
1757
        test    ebx, ebx
1758
        jz      .last_socket
1536 hidnplayr 1759
 
2402 hidnplayr 1760
        cmp     [ebx + SOCKET.Number], edi
1761
        jne     .next_socket
1762
        jmp     .next_socket_number
1159 hidnplayr 1763
 
1514 hidnplayr 1764
  .last_socket:
2402 hidnplayr 1765
        mov     [last_socket_num], edi
1766
        mov     [eax + SOCKET.Number], edi
1767
        DEBUGF  1, "SOCKET_alloc: number=%u\n", edi
1159 hidnplayr 1768
 
1514 hidnplayr 1769
; Fill in PID
2402 hidnplayr 1770
        mov     ebx, [TASK_BASE]
1771
        mov     ebx, [ebx + TASKDATA.pid]
1772
        mov     [eax + SOCKET.PID], ebx
3264 hidnplayr 1773
        mov     [eax + SOCKET.TID], ebx         ; currently TID = PID in kolibrios :(
1514 hidnplayr 1774
 
2403 hidnplayr 1775
; init mutex
1776
        pusha
1777
        lea     ecx, [eax + SOCKET.mutex]
1778
        call    mutex_init
1779
        popa
1780
 
1529 hidnplayr 1781
; add socket to the list by re-arranging some pointers
2402 hidnplayr 1782
        mov     ebx, [net_sockets + SOCKET.NextPtr]
1514 hidnplayr 1783
 
2402 hidnplayr 1784
        mov     [eax + SOCKET.PrevPtr], net_sockets
1785
        mov     [eax + SOCKET.NextPtr], ebx
1514 hidnplayr 1786
 
2402 hidnplayr 1787
        test    ebx, ebx
1788
        jz      @f
1789
 
1790
        pusha
1791
        lea     ecx, [ebx + SOCKET.mutex]
1792
        call    mutex_lock
1793
        popa
1794
 
1795
        mov     [ebx + SOCKET.PrevPtr], eax
1796
 
1797
        pusha
1798
        lea     ecx, [ebx + SOCKET.mutex]
1799
        call    mutex_unlock
1800
        popa
1514 hidnplayr 1801
       @@:
1802
 
2402 hidnplayr 1803
        mov     [net_sockets + SOCKET.NextPtr], eax
1804
        or      eax, eax                ; used to clear zero flag
1159 hidnplayr 1805
  .exit:
2402 hidnplayr 1806
        pop     ebx
1514 hidnplayr 1807
 
2402 hidnplayr 1808
        ret
1159 hidnplayr 1809
 
1514 hidnplayr 1810
 
1811
;----------------------------------------------------
1159 hidnplayr 1812
;
1514 hidnplayr 1813
; SOCKET_free
1159 hidnplayr 1814
;
1514 hidnplayr 1815
; Free socket data memory and remove socket from the list
1816
;
1817
; IN:  eax = socket ptr
1818
; OUT: /
1819
;
1820
;----------------------------------------------------
1821
align 4
1822
SOCKET_free:
1159 hidnplayr 1823
 
2402 hidnplayr 1824
        DEBUGF  1, "SOCKET_free: %x\n", eax
1514 hidnplayr 1825
 
2402 hidnplayr 1826
        call    SOCKET_check
1827
        jz      .error
1159 hidnplayr 1828
 
2402 hidnplayr 1829
        push    ebx
1514 hidnplayr 1830
 
2402 hidnplayr 1831
        pusha
1832
        lea     ecx, [eax + SOCKET.mutex]
1833
        call    mutex_lock
1834
        popa
1514 hidnplayr 1835
 
2402 hidnplayr 1836
        cmp     [eax + SOCKET.Domain], AF_INET4
1837
        jnz     .no_tcp
1529 hidnplayr 1838
 
2402 hidnplayr 1839
        cmp     [eax + SOCKET.Protocol], IP_PROTO_TCP
1840
        jnz     .no_tcp
1841
 
1842
        mov     ebx, eax
1843
        stdcall kernel_free, [ebx + STREAM_SOCKET.rcv.start_ptr]
1844
        stdcall kernel_free, [ebx + STREAM_SOCKET.snd.start_ptr]
1845
        mov     eax, ebx
1536 hidnplayr 1846
  .no_tcp:
1529 hidnplayr 1847
 
2402 hidnplayr 1848
        push    eax                             ; this will be passed to kernel_free
1849
        mov     ebx, [eax + SOCKET.NextPtr]
1850
        mov     eax, [eax + SOCKET.PrevPtr]
1514 hidnplayr 1851
 
2402 hidnplayr 1852
        DEBUGF  1, "SOCKET_free: linking socket %x to socket %x\n", eax, ebx
1514 hidnplayr 1853
 
2402 hidnplayr 1854
        test    eax, eax
1855
        jz      @f
1856
        mov     [eax + SOCKET.NextPtr], ebx
1514 hidnplayr 1857
       @@:
1159 hidnplayr 1858
 
2402 hidnplayr 1859
        test    ebx, ebx
1860
        jz      @f
1861
        mov     [ebx + SOCKET.PrevPtr], eax
1514 hidnplayr 1862
       @@:
1249 hidnplayr 1863
 
2402 hidnplayr 1864
        call    kernel_free
1865
        pop     ebx
1159 hidnplayr 1866
 
2402 hidnplayr 1867
        DEBUGF  1, "SOCKET_free: success!\n"
1514 hidnplayr 1868
 
1159 hidnplayr 1869
  .error:
2402 hidnplayr 1870
        ret
1159 hidnplayr 1871
 
1543 hidnplayr 1872
;------------------------------------
1873
;
1874
; SOCKET_fork
1875
;
1876
; Create a child socket
1877
;
1533 hidnplayr 1878
; IN:  socket nr in ebx
1543 hidnplayr 1879
; OUT: child socket nr in eax
1880
;
1881
;-----------------------------------
1529 hidnplayr 1882
align 4
1883
SOCKET_fork:
1884
 
2402 hidnplayr 1885
        DEBUGF  1,"SOCKET_fork: %x\n", ebx
1529 hidnplayr 1886
 
1543 hidnplayr 1887
; Exit if backlog queue is full
2402 hidnplayr 1888
        mov     eax, [ebx + SOCKET_QUEUE_LOCATION + queue.size]
1889
        cmp     ax, [ebx + SOCKET.backlog]
1890
        jae     .fail
1543 hidnplayr 1891
 
1529 hidnplayr 1892
; Allocate new socket
2402 hidnplayr 1893
        push    ebx
1894
        call    SOCKET_alloc
1895
        pop     ebx
1896
        jz      .fail
1529 hidnplayr 1897
 
2402 hidnplayr 1898
        push    eax
1899
        mov     esi, esp
1900
        add_to_queue (ebx + SOCKET_QUEUE_LOCATION), MAX_backlog, 4, .fail2
1901
        pop     eax
1543 hidnplayr 1902
 
1903
; Copy structure from current socket to new
1904
; We start at PID to preserve the socket num, and the 2 pointers at beginning of socket
2402 hidnplayr 1905
        lea     esi, [ebx + SOCKET.PID]
1906
        lea     edi, [eax + SOCKET.PID]
1907
        mov     ecx, (SOCKET_QUEUE_LOCATION - SOCKET.PID + 3)/4
1908
        rep     movsd
1529 hidnplayr 1909
 
2402 hidnplayr 1910
        and     [eax + SOCKET.options], not SO_ACCEPTCON
1529 hidnplayr 1911
 
2402 hidnplayr 1912
        ret
1529 hidnplayr 1913
 
1543 hidnplayr 1914
  .fail2:
2402 hidnplayr 1915
        add     esp, 4+4+4
1543 hidnplayr 1916
  .fail:
2402 hidnplayr 1917
        DEBUGF  1,"SOCKET_fork: failed\n"
1918
        xor     eax, eax
1919
        ret
1529 hidnplayr 1920
 
1543 hidnplayr 1921
 
1514 hidnplayr 1922
;---------------------------------------------------
1923
;
1924
; SOCKET_num_to_ptr
1925
;
1159 hidnplayr 1926
; Get socket structure address by its number
1927
;
1514 hidnplayr 1928
; IN:  ecx = socket number
1533 hidnplayr 1929
; OUT: eax = 0 on error, socket ptr otherwise
1514 hidnplayr 1930
;       ZF = set on error
1159 hidnplayr 1931
;
1514 hidnplayr 1932
;---------------------------------------------------
1933
align 4
1934
SOCKET_num_to_ptr:
1159 hidnplayr 1935
 
2891 hidnplayr 1936
        DEBUGF  1,"SOCKET_num_to_ptr: num=%u ", ecx
1514 hidnplayr 1937
 
2402 hidnplayr 1938
        mov     eax, net_sockets
1514 hidnplayr 1939
 
1159 hidnplayr 1940
  .next_socket:
2402 hidnplayr 1941
        mov     eax, [eax + SOCKET.NextPtr]
1942
        or      eax, eax
1943
        jz      .error
1944
        cmp     [eax + SOCKET.Number], ecx
1945
        jne     .next_socket
1159 hidnplayr 1946
 
2402 hidnplayr 1947
        test    eax, eax
1159 hidnplayr 1948
 
2891 hidnplayr 1949
        DEBUGF  1,"ptr=%x\n", eax
1950
        ret
1951
 
1159 hidnplayr 1952
  .error:
2891 hidnplayr 1953
        DEBUGF  1,"not found\n", eax
2402 hidnplayr 1954
        ret
1159 hidnplayr 1955
 
1514 hidnplayr 1956
 
1957
;---------------------------------------------------
1159 hidnplayr 1958
;
1514 hidnplayr 1959
; SOCKET_ptr_to_num
1159 hidnplayr 1960
;
1514 hidnplayr 1961
; Get socket number by its address
1962
;
1963
; IN:  eax = socket ptr
1964
; OUT: eax = 0 on error, socket num otherwise
1965
;       ZF = set on error
1966
;
1967
;---------------------------------------------------
1968
align 4
1969
SOCKET_ptr_to_num:
1970
 
2891 hidnplayr 1971
        DEBUGF  1,"SOCKET_ptr_to_num: ptr=%x ", eax
1514 hidnplayr 1972
 
2402 hidnplayr 1973
        call    SOCKET_check
1974
        jz      .error
1159 hidnplayr 1975
 
2402 hidnplayr 1976
        mov     eax, [eax + SOCKET.Number]
1514 hidnplayr 1977
 
2891 hidnplayr 1978
        DEBUGF  1,"num=%u\n", eax
1979
        ret
1514 hidnplayr 1980
 
1981
  .error:
2891 hidnplayr 1982
        DEBUGF  1,"not found\n", eax
2402 hidnplayr 1983
        ret
1514 hidnplayr 1984
 
1985
 
1986
;---------------------------------------------------
1987
;
1988
; SOCKET_check
1989
;
1990
; checks if the given value is really a socket ptr
1991
;
1992
; IN:  eax = socket ptr
1993
; OUT: eax = 0 on error, unchanged otherwise
1994
;       ZF = set on error
1995
;
1996
;---------------------------------------------------
1997
align 4
1998
SOCKET_check:
1999
 
2402 hidnplayr 2000
        DEBUGF  1,"SOCKET_check: %x\n", eax
1514 hidnplayr 2001
 
2402 hidnplayr 2002
        push    ebx
2003
        mov     ebx, net_sockets
1514 hidnplayr 2004
 
1159 hidnplayr 2005
  .next_socket:
2402 hidnplayr 2006
        mov     ebx, [ebx + SOCKET.NextPtr]
2007
        or      ebx, ebx
2008
        jz      .done
2009
        cmp     ebx, eax
2010
        jnz     .next_socket
1159 hidnplayr 2011
 
1514 hidnplayr 2012
  .done:
2402 hidnplayr 2013
        mov     eax, ebx
2014
        test    eax, eax
2015
        pop     ebx
1514 hidnplayr 2016
 
2402 hidnplayr 2017
        ret
1159 hidnplayr 2018
 
1514 hidnplayr 2019
 
2020
 
2021
;---------------------------------------------------
2022
;
2023
; SOCKET_check_owner
2024
;
2025
; checks if the caller application owns the socket
2026
;
2027
; IN:  eax = socket ptr
2028
; OUT:  ZF = true/false
2029
;
2030
;---------------------------------------------------
2031
align 4
2032
SOCKET_check_owner:
2033
 
2402 hidnplayr 2034
        DEBUGF  1,"SOCKET_check_owner: %x\n", eax
1514 hidnplayr 2035
 
2402 hidnplayr 2036
        push    ebx
2037
        mov     ebx, [TASK_BASE]
3257 hidnplayr 2038
        mov     ebx, [ebx + TASKDATA.pid]
2402 hidnplayr 2039
        cmp     [eax + SOCKET.PID], ebx
2040
        pop      ebx
1514 hidnplayr 2041
 
2402 hidnplayr 2042
        ret
1514 hidnplayr 2043
 
2044
 
2045
 
2046
 
1885 hidnplayr 2047
;------------------------------------------------------
1514 hidnplayr 2048
;
2049
; SOCKET_process_end
2050
;
2051
; Kernel calls this function when a certain process ends
2052
; This function will check if the process had any open sockets
2053
; And update them accordingly
2054
;
2867 hidnplayr 2055
; IN:  edx = pid
1514 hidnplayr 2056
; OUT: /
2057
;
2058
;------------------------------------------------------
2059
align 4
2060
SOCKET_process_end:
2061
 
3264 hidnplayr 2062
        DEBUGF  1, "SOCKET_process_end: %x\n", edx
1514 hidnplayr 2063
 
2402 hidnplayr 2064
        push    ebx
2065
        mov     ebx, net_sockets
1514 hidnplayr 2066
 
2067
  .next_socket:
2402 hidnplayr 2068
        mov     ebx, [ebx + SOCKET.NextPtr]
2069
        test    ebx, ebx
2070
        jz      .done
1514 hidnplayr 2071
 
2867 hidnplayr 2072
        cmp     [ebx + SOCKET.PID], edx
2402 hidnplayr 2073
        jne     .next_socket
1514 hidnplayr 2074
 
3264 hidnplayr 2075
        DEBUGF  1, "SOCKET_process_end: killing socket %x\n", ebx
1514 hidnplayr 2076
 
2402 hidnplayr 2077
        mov     [ebx + SOCKET.PID], 0
2078
        mov     eax, ebx
3264 hidnplayr 2079
        pusha
2080
        call    SOCKET_close.socket
2081
        popa
2082
        jmp     .next_socket
1514 hidnplayr 2083
 
2084
  .done:
2402 hidnplayr 2085
        pop     ebx
1514 hidnplayr 2086
 
2402 hidnplayr 2087
        ret
1773 hidnplayr 2088
 
2089
 
2090
 
2091
 
1885 hidnplayr 2092
;-----------------------------------------------------------------
2093
;
2094
; SOCKET_is_connecting
2095
;
2096
;  IN:  eax = socket ptr
2097
;  OUT: /
2098
;
2099
;-----------------------------------------------------------------
1773 hidnplayr 2100
 
1885 hidnplayr 2101
align 4
2102
SOCKET_is_connecting:
1773 hidnplayr 2103
 
2891 hidnplayr 2104
        DEBUGF  1,"SOCKET_is_connecting: %x\n", eax
1773 hidnplayr 2105
 
2402 hidnplayr 2106
        and     [eax + SOCKET.options], not (SS_ISCONNECTED + SS_ISDISCONNECTING + SS_ISCONFIRMING)
2107
        or      [eax + SOCKET.options], SS_ISCONNECTING
1773 hidnplayr 2108
 
3257 hidnplayr 2109
        jmp     SOCKET_notify
1885 hidnplayr 2110
 
2111
 
2112
 
1773 hidnplayr 2113
;-----------------------------------------------------------------
2114
;
1885 hidnplayr 2115
; SOCKET_is_connected
2116
;
2117
;  IN:  eax = socket ptr
2118
;  OUT: /
2119
;
2120
;-----------------------------------------------------------------
2121
 
2122
align 4
2123
SOCKET_is_connected:
2124
 
2891 hidnplayr 2125
        DEBUGF  1,"SOCKET_is_connected: %x\n", eax
1885 hidnplayr 2126
 
2402 hidnplayr 2127
        and     [eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISDISCONNECTING + SS_ISCONFIRMING)
2128
        or      [eax + SOCKET.options], SS_ISCONNECTED
1885 hidnplayr 2129
 
3257 hidnplayr 2130
        jmp     SOCKET_notify
1885 hidnplayr 2131
 
2132
 
2133
 
2134
 
2135
;-----------------------------------------------------------------
2136
;
1773 hidnplayr 2137
; SOCKET_is_disconnecting
2138
;
2139
;  IN:  eax = socket ptr
2140
;  OUT: /
2141
;
2142
;-----------------------------------------------------------------
2143
 
2144
align 4
2145
SOCKET_is_disconnecting:
2146
 
2891 hidnplayr 2147
        DEBUGF  1,"SOCKET_is_disconnecting: %x\n", eax
2148
 
2402 hidnplayr 2149
        and     [eax + SOCKET.options], not (SS_ISCONNECTING)
2150
        or      [eax + SOCKET.options], SS_ISDISCONNECTING + SS_CANTRCVMORE + SS_CANTSENDMORE
1773 hidnplayr 2151
 
3257 hidnplayr 2152
        jmp     SOCKET_notify
1773 hidnplayr 2153
 
2154
 
2155
 
2156
;-----------------------------------------------------------------
2157
;
2158
; SOCKET_is_disconnected
2159
;
2160
;  IN:  eax = socket ptr
2161
;  OUT: /
2162
;
2163
;-----------------------------------------------------------------
2164
 
2165
align 4
2166
SOCKET_is_disconnected:
2167
 
2891 hidnplayr 2168
        DEBUGF  1,"SOCKET_is_disconnected: %x\n", eax
2169
 
2402 hidnplayr 2170
        and     [eax + SOCKET.options], not (SS_ISCONNECTING + SS_ISCONNECTED + SS_ISDISCONNECTING)
2171
        or      [eax + SOCKET.options], SS_CANTRCVMORE + SS_CANTSENDMORE
1773 hidnplayr 2172
 
3257 hidnplayr 2173
        jmp     SOCKET_notify
1774 hidnplayr 2174
 
2175
 
2176
;-----------------------------------------------------------------
2177
;
2178
; SOCKET_cant_recv_more
2179
;
2180
;  IN:  eax = socket ptr
2181
;  OUT: /
2182
;
2183
;-----------------------------------------------------------------
2184
 
2185
align 4
2186
SOCKET_cant_recv_more:
2187
 
2891 hidnplayr 2188
        DEBUGF  1,"SOCKET_cant_recv_more: %x\n", eax
2189
 
2402 hidnplayr 2190
        or      [eax + SOCKET.options], SS_CANTRCVMORE
1885 hidnplayr 2191
 
2402 hidnplayr 2192
        ret
1831 hidnplayr 2193
 
2194
 
2195
 
2196
;-----------------------------------------------------------------
2197
;
1885 hidnplayr 2198
; SOCKET_cant_send_more
1831 hidnplayr 2199
;
2200
;  IN:  eax = socket ptr
2201
;  OUT: /
2202
;
2203
;-----------------------------------------------------------------
2204
 
2205
align 4
1885 hidnplayr 2206
SOCKET_cant_send_more:
1831 hidnplayr 2207
 
2891 hidnplayr 2208
        DEBUGF  1,"SOCKET_cant_send_more: %x\n", eax
2209
 
2402 hidnplayr 2210
        or      [eax + SOCKET.options], SS_CANTSENDMORE
1831 hidnplayr 2211
 
2402 hidnplayr 2212
        ret