A2osX/LIB/LIBTCPIP.S.TCP.txt
2019-10-28 17:20:40 +01:00

589 lines
13 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

NEW
AUTO 3,1
.LIST OFF
*--------------------------------------
TCP.IN jsr FRM.GetTargetSKT.TCPUDP
jsr SKT.FindMatchingLocRem
bcs TCP.IN.JMP.DISCARD no socket, go discard
ldy #S.TCP.OPTIONS
lda (ZPFrameInPtr),y
and #S.TCP.OPTIONS.RST RST ? go Kill this socket...
bne TCP.IN.RST ...and discard frame
ldy #S.SOCKET.TCP.S
lda (ZPPtrSKT),y
asl
tax
jmp (J.TCP.IN,x)
*--------------------------------------
TCP.IN.RST lda SKT.TABLE,x
jsr SKT.shutdown
*--------------------------------------
TCP.IN.JMP.OPENED
TCP.IN.JMP.CLOSED
TCP.IN.JMP.DISCARD
lda hFrameIn
stz hFrameIn
>SYSCALL2 FreeMem
rts
*--------------------------------------
TCP.IN.JMP.LISTEN
ldy #S.SOCKET.T Create a new client socket
lda (ZPPtrSKT),y
tax Same type a listening socket
iny #S.SOCKET.PROTO
lda (ZPPtrSKT),y
jsr SKT.Socket.I get new socket in ZPTmpPtr1
bcs TCP.IN.JMP.DISCARD
jsr SKT.AddToQueueA Queued successfully ?
bcs TCP.IN.JMP.DISCARD no, discard frame and new socket
jsr ARP.AddFromFrameInPtr
lda ZPTmpPtr1
sta ZPPtrSKT
lda ZPTmpPtr1+1
sta ZPPtrSKT+1
jsr SKT.SetLocAddr
jsr SKT.SetRemAddr
jsr SKT.NewTCB
bcs .99
jsr TCP.IN.ACKTheSYN
lda #S.TCP.OPTIONS.SYN+S.TCP.OPTIONS.ACK
jsr TCP.OUT.SendOptA SYN received, Send SYN.ACK
bcs .9
lda #S.SOCKET.TCP.S.SYNRCVD
jmp SKT.StoreTCB.S
.9 lda #ERR.SKT.OOS
.99 rts
*--------------------------------------
TCP.IN.JMP.SYNSENT
ldy #S.TCP.OPTIONS SYN Send, only accept SYN.ACK packet, then Send ACK
lda (ZPFrameInPtr),y
and #S.TCP.OPTIONS.SYN+S.TCP.OPTIONS.ACK
cmp #S.TCP.OPTIONS.SYN+S.TCP.OPTIONS.ACK
bne .9
jsr SKT.GetTCB
ldx #3
ldy #S.TCP.ACKNUM+3
sec Check if ACK=OUTNEXTSEQ+1
.1 lda SKT.Cache+S.SOCKET.TCP.OUTNEXTSEQ,x
adc #0
sta SKT.Cache+S.SOCKET.TCP.OUTNEXTSEQ,x
eor (ZPFrameInPtr),y
bne .9
dey
dex
bpl .1
jsr TCP.IN.ACKTheSYN
lda #S.TCP.OPTIONS.ACK
jsr TCP.OUT.SendOptA SYN.ACK received, Send, ACK
bcs .9
lda #S.SOCKET.TCP.S.ESTBLSH
jmp SKT.StoreTCB.S
.9 lda #S.TCP.OPTIONS.RST
jsr TCP.OUT.SendOptA Send RST
ldx SKT.Index
lda SKT.TABLE,x
jmp SKT.shutdown
*--------------------------------------
TCP.IN.JMP.SYNRCVD
ldy #S.TCP.OPTIONS SYN Received, SYN.ACK Sent, only accept ACK packet
lda (ZPFrameInPtr),y
cmp #S.TCP.OPTIONS.ACK
bne .8
jsr SKT.GetTCB
ldx #3
ldy #S.TCP.ACKNUM+3
sec
.1 lda SKT.Cache+S.SOCKET.TCP.OUTNEXTSEQ,x Check if ACK=OUTNEXTSEQ+1
adc #0
sta SKT.Cache+S.SOCKET.TCP.OUTSENTSEQ,x setup SEQNUM
sta SKT.Cache+S.SOCKET.TCP.OUTNEXTSEQ,x ...and update NEXTSEQ
eor (ZPFrameInPtr),y
bne .8
dey
dex
bpl .1
lda #S.SOCKET.TCP.S.ESTBLSH
jmp SKT.StoreTCB.S
.8 clc
.9 rts
*--------------------------------------
TCP.IN.JMP.ESTBLSH
.DO IPDEBUG=1
jsr DEBUG.IPID
.FIN
jsr SKT.GetTCB
ldy #S.TCP.OPTIONS
lda (ZPFrameInPtr),y
and #S.TCP.OPTIONS.ACK Remote side ACKed data ?
beq .4
* Ack sent data
ldy #S.TCP.ACKNUM+3 Get new ACK number from FrameIn...
ldx #3 Substract old ACK from socket
sec
.1 lda (ZPFrameInPtr),y
pha
sbc SKT.Cache+S.SOCKET.TCP.OUTSENTSEQ,x
sta TmpDWord,x
pla ....and Set SEQ = new SEQ
sta SKT.Cache+S.SOCKET.TCP.OUTSENTSEQ,x
dey
dex
bpl .1
lda TmpDWord+3
ldx TmpDWord+2
bne .2
tay
beq .4
.2 pha
clc
adc SKT.Cache+S.SOCKET.TCP.OUTTAIL
sta SKT.Cache+S.SOCKET.TCP.OUTTAIL
txa
adc SKT.Cache+S.SOCKET.TCP.OUTTAIL+1
and /K.TCP.WSIZE-1
sta SKT.Cache+S.SOCKET.TCP.OUTTAIL+1
pla
clc
adc SKT.Cache+S.SOCKET.TCP.OUTFREE
sta SKT.Cache+S.SOCKET.TCP.OUTFREE
txa
adc SKT.Cache+S.SOCKET.TCP.OUTFREE+1
sta SKT.Cache+S.SOCKET.TCP.OUTFREE+1
lda SKT.Cache+S.SOCKET.TCP.OUTUSED
sec
sbc TmpDWord+3
sta SKT.Cache+S.SOCKET.TCP.OUTUSED
lda SKT.Cache+S.SOCKET.TCP.OUTUSED+1
sbc TmpDWord+2
sta SKT.Cache+S.SOCKET.TCP.OUTUSED+1
jsr SKT.StoreTCB
* Store incoming data
.4 jsr TCP.IN.SetDataInPtrAndLen
lda ZPDataInLen Incoming Data in this frame ?
ora ZPDataInLen+1
beq .7 No data, ...
ldy #S.TCP.SEQNUM+3
ldx #3
.5 lda (ZPFrameInPtr),y
eor SKT.Cache+S.SOCKET.TCP.INSEQNUM,x
bne .9 Missed a frame.....
.51 dey
dex
bpl .5
ldy #S.SOCKET.T Create a new client socket
lda (ZPPtrSKT),y
cmp #S.SOCKET.T.STREAM
bne .52
jsr SKT.AddDataToSktIn yes, queue data if there is room for....
bra .59
.52 lda hFrameIn
jsr SKT.AddToQueueA
bcs .9
.59 lda ZPDataInLen
ldy ZPDataInLen+1
ldx #S.SOCKET.TCP.INSEQNUM
jsr TCP.AddAYToSktCacheAtX
.6 jsr SKT.StoreTCB update socket
* jsr TCP.SetSocketTCPO.ACK ...and ack data
lda #S.TCP.OPTIONS.ACK
jsr TCP.OUT.SendOptA
* bcs *
.7 ldy #S.TCP.OPTIONS
lda (ZPFrameInPtr),y
and #S.TCP.OPTIONS.FIN
beq .8
lda #S.SOCKET.TCP.S.CLWAIT
ldy #S.SOCKET.TCP.S
sta (ZPPtrSKT),y
jsr TCP.IN.ACKTheFIN
lda #S.TCP.OPTIONS.FIN+S.TCP.OPTIONS.ACK
jsr TCP.SetSocketTCPO FIN received, Send FIN.ACK
* jsr TCP.OUT.SendOptA
.8 clc
rts
.9 sec
rts
*--------------------------------------
TCP.IN.JMP.LASTACK
ldy #S.TCP.OPTIONS only accept ACK packet
lda (ZPFrameInPtr),y
bit #S.TCP.OPTIONS.ACK
beq .8
ldy #S.SOCKET.TCP.S
lda #S.SOCKET.TCP.S.TIMEWT
sta (ZPPtrSKT),y
.8
*--------------------------------------
TCP.IN.JMP.CLWAIT
clc Wait for SKT.shutdown
rts
*--------------------------------------
TCP.IN.JMP.FINWT1
jsr SKT.GetTCB
ldy #S.TCP.OPTIONS FIN sent, accept ACK or FIN/ACK packet
lda (ZPFrameInPtr),y
bit #S.TCP.OPTIONS.FIN
bne .1
lda #S.TCP.OPTIONS.FIN+S.TCP.OPTIONS.ACK
jsr TCP.OUT.SendOptA Send FIN.ACK
bcs TCP.IN.JMP.TIMEWT.RTS
lda #S.SOCKET.TCP.S.FINWT2
jmp SKT.StoreTCB.S
.1 jsr TCP.IN.ACKTheFIN FIN/ACK
lda #S.TCP.OPTIONS.FIN+S.TCP.OPTIONS.ACK
bra TCP.IN.JMP.FINWT.ACK Send FIN.ACK
*--------------------------------------
TCP.IN.JMP.FINWT2
ldy #S.TCP.OPTIONS only accept ACK packet
lda (ZPFrameInPtr),y
bit #S.TCP.OPTIONS.ACK
beq TCP.IN.JMP.TIMEWT
jsr SKT.GetTCB
jsr TCP.IN.ACKTheFIN
lda #S.TCP.OPTIONS.ACK
TCP.IN.JMP.FINWT.ACK
jsr TCP.OUT.SendOptA FIN received, Send ACK
bcs TCP.IN.JMP.TIMEWT.RTS
lda #S.SOCKET.TCP.S.TIMEWT
jmp SKT.StoreTCB.S
*--------------------------------------
TCP.IN.JMP.CLOSING
ldy #S.TCP.OPTIONS only accept ACK packet
lda (ZPFrameInPtr),y
bit #S.TCP.OPTIONS.ACK
beq .1
ldy #S.SOCKET.TCP.S
lda #S.SOCKET.TCP.S.TIMEWT
sta (ZPPtrSKT),y
.1
* clc
* rts
*--------------------------------------
TCP.IN.JMP.TIMEWT
clc Wait for TCP.Close
TCP.IN.JMP.TIMEWT.RTS
rts
*--------------------------------------
TCP.IN.ACKTheSYN
ldy #S.TCP.SEQNUM+3 Get Remote SEQ
ldx #3
sec
.3 lda (ZPFrameInPtr),y Set OUTACK=SEQ+1 for new socket...
adc #0
sta SKT.Cache+S.SOCKET.TCP.INSEQNUM,x
dey
dex
bpl .3
rts
*--------------------------------------
TCP.IN.ACKTheFIN
jsr TCP.SetSocketTCPO.ACK
ldx #3
.1 inc SKT.Cache+S.SOCKET.TCP.INSEQNUM,x
bne .8
dex
bpl .1
.8 rts
*--------------------------------------
TCP.IN.SetDataInPtrAndLen
ldy #S.IP.TOTAL.LENGTH+1
lda (ZPFrameInPtr),y
sec
sbc #S.IP-S.ETH.EII
sta ZPDataInLen
dey
lda (ZPFrameInPtr),y
sbc /S.IP-S.ETH.EII
sta ZPDataInLen+1
ldy #S.TCP.DATAOFFSET
lda (ZPFrameInPtr),y
and #$F0 Get TCP Header len in DWORD
lsr
lsr
sta ZPDataInPtr TMP Storage
lda ZPDataInLen
sec
sbc ZPDataInPtr TMP Storage
sta ZPDataInLen
bcs .1
dec ZPDataInLen+1
.1 lda ZPFrameInPtr
clc
adc #S.IP
pha
lda ZPFrameInPtr+1
adc /S.IP
tax
pla
clc
adc ZPDataInPtr TMP Storage
bcc .2
inx
.2 sta ZPDataInPtr
stx ZPDataInPtr+1
TCP.IN.RTS rts
*--------------------------------------
TCP.SENDCLOSE ldx #0
.1 phx
lda SKT.TABLE,x
beq .8
>SYSCALL2 GetMemPtr
>STYA ZPPtrSKT
ldy #S.SOCKET.AF
lda (ZPPtrSKT),y
cmp #AF.INET
bne .8
iny #S.SOCKET.T
lda (ZPPtrSKT),y
cmp #S.SOCKET.T.SEQPACKET
bcc .8
ldy #S.SOCKET.TCP.S
lda (ZPPtrSKT),y
cmp #S.SOCKET.TCP.S.TIMEWT
beq .4
cmp #S.SOCKET.TCP.S.ESTBLSH
bne .2
jsr SKT.GetTCB
jsr TCP.OUT
bra .8
.2 cmp #S.SOCKET.TCP.S.OPENED
bne .8
jsr SKT.GetTCB
lda #S.TCP.OPTIONS.SYN
jsr TCP.OUT.SendOptA Send SYN
bcs .8 failed ARP lookup....
lda #S.SOCKET.TCP.S.SYNSENT
jsr SKT.StoreTCB.S
bra .8
lda #S.TCP.OPTIONS.SYN
jsr TCP.OUT.SendOptA Send SYN
bra .8
.4 ldy #S.SOCKET.SQ.hInMem
lda (ZPPtrSKT),y
beq .5
.DO AUXPIPE=1
>SYSCALL2 FreeStkObj
.ELSE
>SYSCALL2 freemem
.FIN
.5 ldy #S.SOCKET.SQ.hOutMem
lda (ZPPtrSKT),y
beq .6
.DO AUXPIPE=1
>SYSCALL2 FreeStkObj
.ELSE
>SYSCALL2 freemem
.FIN
.6 plx
phx
lda SKT.TABLE,x
stz SKT.TABLE,x
>SYSCALL2 freemem
.8 plx
inx
cpx #K.SKTTABLE.SIZE
bne .1
.9 rts
*--------------------------------------
TCP.OUT lda SKT.Cache+S.SOCKET.TCP.OUTTOSEND+1
ldy SKT.Cache+S.SOCKET.TCP.OUTTOSEND
bne .1
tax
bne .1
* Y,A=0 : no data to send
ldy #S.SOCKET.TCP.O
lda (ZPPtrSKT),y
bne TCP.OUT.SendOptA a least an option...
clc No data, no flag....exit
.9 rts
.1 cpy #K.TCP.MSS
pha
sbc /K.TCP.MSS OUTDATA > MSS ?
pla
bcc .2 no....keep data len
>LDYAI K.TCP.MSS yes send only MSS
.2 jsr TCP.NewFrame
bcs .9
jsr SKT.GetDataFromSktOut
ldy #S.TCP.WINDOW
lda SKT.Cache+S.SOCKET.TCP.INFREE+1
sta (ZPFrameOutPtr),y
iny
lda SKT.Cache+S.SOCKET.TCP.INFREE
sta (ZPFrameOutPtr),y
lda #S.TCP.OPTIONS.ACK+S.TCP.OPTIONS.PSH
jsr TCP.OUT.Send
bcs .9
lda ZPDataOutLen
ldy ZPDataOutLen+1
ldx #S.SOCKET.TCP.OUTNEXTSEQ
jsr TCP.AddAYToSktCacheAtX
jmp SKT.StoreTCB exits with CC
*--------------------------------------
TCP.OUT.SendOptA
jsr TCP.SetSocketTCPO
>LDYAI 0
jsr TCP.NewFrame
bcs TCP.OUT.Send.9
ldy #S.SOCKET.TCP.INFREE+1
lda (ZPPtrSKT),y
tax
dey
lda (ZPPtrSKT),y
ldy #S.TCP.WINDOW+1
sta (ZPFrameOutPtr),y
dey
txa
sta (ZPFrameOutPtr),y
ldy #S.SOCKET.TCP.O
lda (ZPPtrSKT),y
TCP.OUT.Send ldy #S.TCP.OPTIONS
sta (ZPFrameOutPtr),y
bit #S.TCP.OPTIONS.ACK
beq .2
ldx #3
ldy #S.TCP.ACKNUM+3
.1 lda SKT.Cache+S.SOCKET.TCP.INSEQNUM,x
sta (ZPFrameOutPtr),y
dey
dex
bpl .1
.2 ldx #3
ldy #S.TCP.SEQNUM+3
.3 lda SKT.Cache+S.SOCKET.TCP.OUTNEXTSEQ,x
sta (ZPFrameOutPtr),y
dey
dex
bpl .3
sec DONT Queue if fail
jsr FRM.SendIP
bcs TCP.OUT.Send.9
ldy #S.SOCKET.TCP.O
lda #0
sta (ZPPtrSKT),y
* clc
TCP.OUT.Send.9 rts
*--------------------------------------
TCP.SetSocketTCPO.ACK
lda #S.TCP.OPTIONS.ACK
TCP.SetSocketTCPO
ldy #S.SOCKET.TCP.O
ora (ZPPtrSKT),y
sta (ZPPtrSKT),y
rts
*--------------------------------------
TCP.NewFrame ldx #S.IP.PROTOCOL.TCP
jsr FRM.NewIP
bcs .9
jsr SKT.SetFrameOutDstIP
jsr SKT.SetFrameOutTCPUDPPorts
ldy #S.TCP.DATAOFFSET
lda #$50 Header size = 5 DWORDS
sta (ZPFrameOutPtr),y
clc
.9 rts
*--------------------------------------
TCP.AddAYToSktCacheAtX
clc
adc SKT.Cache+3,x
sta SKT.Cache+3,x
tya
adc SKT.Cache+2,x
sta SKT.Cache+2,x
bcc .8
inc SKT.Cache+1,x
bne .8
inc SKT.Cache,x
.8 rts
*--------------------------------------
.DO IPDEBUG=1
DEBUG.IPID ldy #S.IP.IDENTIFICATION
lda (ZPFrameInPtr),y
>PUSHA
iny
lda (ZPFrameInPtr),y
>PUSHA
>PUSHBI 2
>LDYA L.MSG.IPID
>SYSCALL printf
rts
.FIN
*--------------------------------------
MAN
SAVE USR/SRC/LIB/LIBTCPIP.S.TCP
LOAD USR/SRC/LIB/LIBTCPIP.S
ASM