Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
8ad2e352
Commit
8ad2e352
authored
Jan 23, 2003
by
Sridhar Samudrala
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[SCTP] Fix to update rwnd on partial reads.
parent
5e595b1c
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
77 additions
and
58 deletions
+77
-58
include/net/sctp/structs.h
include/net/sctp/structs.h
+2
-0
net/sctp/associola.c
net/sctp/associola.c
+67
-0
net/sctp/socket.c
net/sctp/socket.c
+6
-0
net/sctp/ulpevent.c
net/sctp/ulpevent.c
+2
-58
No files found.
include/net/sctp/structs.h
View file @
8ad2e352
...
...
@@ -1633,6 +1633,8 @@ __u32 __sctp_association_get_tsn_block(sctp_association_t *, int);
__u16
__sctp_association_get_next_ssn
(
sctp_association_t
*
,
__u16
sid
);
void
sctp_assoc_sync_pmtu
(
sctp_association_t
*
);
void
sctp_assoc_rwnd_increase
(
sctp_association_t
*
,
int
);
void
sctp_assoc_rwnd_decrease
(
sctp_association_t
*
,
int
);
int
sctp_cmp_addr_exact
(
const
union
sctp_addr
*
ss1
,
const
union
sctp_addr
*
ss2
);
...
...
net/sctp/associola.c
View file @
8ad2e352
...
...
@@ -977,3 +977,70 @@ void sctp_assoc_sync_pmtu(sctp_association_t *asoc)
SCTP_DEBUG_PRINTK
(
"%s: asoc:%p, pmtu:%d, frag_point:%d
\n
"
,
__FUNCTION__
,
asoc
,
asoc
->
pmtu
,
asoc
->
frag_point
);
}
/* Increase asoc's rwnd by len and send any window update SACK if needed. */
void
sctp_assoc_rwnd_increase
(
sctp_association_t
*
asoc
,
int
len
)
{
sctp_chunk_t
*
sack
;
struct
timer_list
*
timer
;
if
(
asoc
->
rwnd_over
)
{
if
(
asoc
->
rwnd_over
>=
len
)
{
asoc
->
rwnd_over
-=
len
;
}
else
{
asoc
->
rwnd
+=
(
len
-
asoc
->
rwnd_over
);
asoc
->
rwnd_over
=
0
;
}
}
else
{
asoc
->
rwnd
+=
len
;
}
SCTP_DEBUG_PRINTK
(
"%s: asoc %p rwnd increased by %d to (%u, %u) - %u
\n
"
,
__FUNCTION__
,
asoc
,
len
,
asoc
->
rwnd
,
asoc
->
rwnd_over
,
asoc
->
a_rwnd
);
/* Send a window update SACK if the rwnd has increased by at least the
* minimum of the association's PMTU and half of the receive buffer.
* The algorithm used is similar to the one described in
* Section 4.2.3.3 of RFC 1122.
*/
if
((
asoc
->
state
==
SCTP_STATE_ESTABLISHED
)
&&
(
asoc
->
rwnd
>
asoc
->
a_rwnd
)
&&
((
asoc
->
rwnd
-
asoc
->
a_rwnd
)
>=
min_t
(
__u32
,
(
asoc
->
base
.
sk
->
rcvbuf
>>
1
),
asoc
->
pmtu
)))
{
SCTP_DEBUG_PRINTK
(
"%s: Sending window update SACK- asoc: %p "
"rwnd: %u a_rwnd: %u
\n
"
,
__FUNCTION__
,
asoc
,
asoc
->
rwnd
,
asoc
->
a_rwnd
);
sack
=
sctp_make_sack
(
asoc
);
if
(
!
sack
)
return
;
/* Update the last advertised rwnd value. */
asoc
->
a_rwnd
=
asoc
->
rwnd
;
asoc
->
peer
.
sack_needed
=
0
;
asoc
->
peer
.
next_dup_tsn
=
0
;
sctp_outq_tail
(
&
asoc
->
outqueue
,
sack
);
/* Stop the SACK timer. */
timer
=
&
asoc
->
timers
[
SCTP_EVENT_TIMEOUT_SACK
];
if
(
timer_pending
(
timer
)
&&
del_timer
(
timer
))
sctp_association_put
(
asoc
);
}
}
/* Decrease asoc's rwnd by len. */
void
sctp_assoc_rwnd_decrease
(
sctp_association_t
*
asoc
,
int
len
)
{
SCTP_ASSERT
(
asoc
->
rwnd
,
"rwnd zero"
,
return
);
SCTP_ASSERT
(
!
asoc
->
rwnd_over
,
"rwnd_over not zero"
,
return
);
if
(
asoc
->
rwnd
>=
len
)
{
asoc
->
rwnd
-=
len
;
}
else
{
asoc
->
rwnd_over
=
len
-
asoc
->
rwnd
;
asoc
->
rwnd
=
0
;
}
SCTP_DEBUG_PRINTK
(
"%s: asoc %p rwnd decreased by %d to (%u, %u)
\n
"
,
__FUNCTION__
,
asoc
,
len
,
asoc
->
rwnd
,
asoc
->
rwnd_over
);
}
net/sctp/socket.c
View file @
8ad2e352
...
...
@@ -1191,6 +1191,12 @@ SCTP_STATIC int sctp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr
goto
out_free
;
sctp_skb_pull
(
skb
,
copied
);
skb_queue_head
(
&
sk
->
receive_queue
,
skb
);
/* When only partial message is copied to the user, increase
* rwnd by that amount. If all the data in the skb is read,
* rwnd is updated when the skb's destructor is called via
* sctp_ulpevent_free().
*/
sctp_assoc_rwnd_increase
(
event
->
asoc
,
copied
);
goto
out
;
}
else
{
msg
->
msg_flags
|=
MSG_EOR
;
...
...
net/sctp/ulpevent.c
View file @
8ad2e352
...
...
@@ -772,9 +772,6 @@ static void sctp_rcvmsg_rfree(struct sk_buff *skb)
{
sctp_association_t
*
asoc
;
sctp_ulpevent_t
*
event
;
sctp_chunk_t
*
sack
;
struct
timer_list
*
timer
;
int
skb_len
=
skb_headlen
(
skb
);
/* Current stack structures assume that the rcv buffer is
* per socket. For UDP style sockets this is not true as
...
...
@@ -784,50 +781,7 @@ static void sctp_rcvmsg_rfree(struct sk_buff *skb)
*/
event
=
(
sctp_ulpevent_t
*
)
skb
->
cb
;
asoc
=
event
->
asoc
;
if
(
asoc
->
rwnd_over
)
{
if
(
asoc
->
rwnd_over
>=
skb_len
)
{
asoc
->
rwnd_over
-=
skb_len
;
}
else
{
asoc
->
rwnd
+=
(
skb_len
-
asoc
->
rwnd_over
);
asoc
->
rwnd_over
=
0
;
}
}
else
{
asoc
->
rwnd
+=
skb_len
;
}
SCTP_DEBUG_PRINTK
(
"rwnd increased by %d to (%u, %u) - %u
\n
"
,
skb_len
,
asoc
->
rwnd
,
asoc
->
rwnd_over
,
asoc
->
a_rwnd
);
/* Send a window update SACK if the rwnd has increased by at least the
* minimum of the association's PMTU and half of the receive buffer.
* The algorithm used is similar to the one described in
* Section 4.2.3.3 of RFC 1122.
*/
if
((
asoc
->
state
==
SCTP_STATE_ESTABLISHED
)
&&
(
asoc
->
rwnd
>
asoc
->
a_rwnd
)
&&
((
asoc
->
rwnd
-
asoc
->
a_rwnd
)
>=
min_t
(
__u32
,
(
asoc
->
base
.
sk
->
rcvbuf
>>
1
),
asoc
->
pmtu
)))
{
SCTP_DEBUG_PRINTK
(
"Sending window update SACK- rwnd: %u "
"a_rwnd: %u
\n
"
,
asoc
->
rwnd
,
asoc
->
a_rwnd
);
sack
=
sctp_make_sack
(
asoc
);
if
(
!
sack
)
goto
out
;
/* Update the last advertised rwnd value. */
asoc
->
a_rwnd
=
asoc
->
rwnd
;
asoc
->
peer
.
sack_needed
=
0
;
asoc
->
peer
.
next_dup_tsn
=
0
;
sctp_outq_tail
(
&
asoc
->
outqueue
,
sack
);
/* Stop the SACK timer. */
timer
=
&
asoc
->
timers
[
SCTP_EVENT_TIMEOUT_SACK
];
if
(
timer_pending
(
timer
)
&&
del_timer
(
timer
))
sctp_association_put
(
asoc
);
}
out:
sctp_assoc_rwnd_increase
(
asoc
,
skb_headlen
(
skb
));
sctp_association_put
(
asoc
);
}
...
...
@@ -835,7 +789,6 @@ static void sctp_rcvmsg_rfree(struct sk_buff *skb)
static
void
sctp_ulpevent_set_owner_r
(
struct
sk_buff
*
skb
,
sctp_association_t
*
asoc
)
{
sctp_ulpevent_t
*
event
;
int
skb_len
=
skb_headlen
(
skb
);
/* The current stack structures assume that the rcv buffer is
* per socket. For UDP-style sockets this is not true as
...
...
@@ -850,16 +803,7 @@ static void sctp_ulpevent_set_owner_r(struct sk_buff *skb, sctp_association_t *a
skb
->
destructor
=
sctp_rcvmsg_rfree
;
SCTP_ASSERT
(
asoc
->
rwnd
,
"rwnd zero"
,
return
);
SCTP_ASSERT
(
!
asoc
->
rwnd_over
,
"rwnd_over not zero"
,
return
);
if
(
asoc
->
rwnd
>=
skb_len
)
{
asoc
->
rwnd
-=
skb_len
;
}
else
{
asoc
->
rwnd_over
=
skb_len
-
asoc
->
rwnd
;
asoc
->
rwnd
=
0
;
}
SCTP_DEBUG_PRINTK
(
"rwnd decreased by %d to (%u, %u)
\n
"
,
skb_len
,
asoc
->
rwnd
,
asoc
->
rwnd_over
);
sctp_assoc_rwnd_decrease
(
asoc
,
skb_headlen
(
skb
));
}
/* A simple destructor to give up the reference to the association. */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment