Browse Source

add socket_fastopen, socket_fastopen_connect4, socket_fastopen_connect6 and socket_quickack

master
Felix von Leitner 7 years ago
parent
commit
ad239137bf
  1. 1
      CHANGES
  2. 22
      socket.h
  3. 2
      socket/socket_connect4.3
  4. 2
      socket/socket_connect6.3
  5. 30
      socket/socket_fastopen.3
  6. 58
      socket/socket_fastopen_connect4.3
  7. 60
      socket/socket_fastopen_connect6.3
  8. 38
      socket/socket_quickack.3
  9. 18
      socket/socket_quickack.c
  10. 2
      socket/socket_send4.3
  11. 8
      socket/socket_send4.c
  12. 2
      socket/socket_send6.3
  13. 8
      socket/socket_send6.c

1
CHANGES

@ -17,6 +17,7 @@
introduce io_eagain_read and io_eagain_write (discontinue using io_eagain plz)
fix buffer_get
add fmt_html_tagarg, fmt_xml, scan_html_tagarg
add socket_fastopen, socket_fastopen_connect4, socket_fastopen_connect6 and socket_quickack
0.29:
save 8 bytes in taia.h for 64-bit systems

22
socket.h

@ -39,7 +39,9 @@ int socket_accept6(int s,char* ip,uint16* port,uint32* scope_id);
ssize_t socket_recv4(int s,char* buf,size_t len,char* ip,uint16* port);
ssize_t socket_recv6(int s,char* buf,size_t len,char* ip,uint16* port,uint32* scope_id);
ssize_t socket_send4(int s,const char* buf,size_t len,const char* ip,uint16 port);
ssize_t socket_send4_flag(int s,const char* buf,size_t len,const char* ip,uint16 port,int flags);
ssize_t socket_send6(int s,const char* buf,size_t len,const char* ip,uint16 port,uint32 scope_id);
ssize_t socket_send6_flag(int s,const char* buf,size_t len,const char* ip,uint16 port,uint32 scope_id,int flags);
int socket_local4(int s,char* ip,uint16* port);
int socket_local6(int s,char* ip,uint16* port,uint32* scope_id);
int socket_remote4(int s,char* ip,uint16* port);
@ -60,7 +62,7 @@ int socket_mchopcount6(int s,char hops);
int socket_mcloop4(int s,char loop);
int socket_mcloop6(int s,char loop);
/* please note that these are platform specific. Do not expect them to
/* Please note that these are platform specific. Do not expect them to
* work. You might still get an accept() signalled even though there is
* no data available. So far, DATAIN is supported on FreeBSD and Linux,
* and HTTPIN is supported on FreeBSD. */
@ -78,6 +80,24 @@ uint32 socket_getifidx(const char* ifname);
extern int noipv6;
/* if HAVE_SOCKET_FASTOPEN is #defined, your version of libowfat
* has socket_fastopen, socket_fastopen_connect4,
* socket_fastopen_connect6 and socket_quickack */
#define HAVE_SOCKET_FASTOPEN
/* Turn on server-side TCP fast open support (0 success, -1 error) */
int socket_fastopen(int s);
/* Turn quick ack mode on or off for the socket s. */
int socket_quickack(int s,int value);
/* For client-side TCP fast open, connect and sending the first data is
* just one step, so we need an API to do it in one step */
ssize_t socket_fastopen_connect4(int s,const char* ip,uint16 port,const char* buf,size_t len);
ssize_t socket_fastopen_connect6(int s,const char* ip,uint16 port,uint32 scope_id,const char* buf,size_t len);
#ifdef __MINGW32__
#include <winsock2.h>
#include <ws2tcpip.h>

2
socket/socket_connect4.3

@ -45,4 +45,4 @@ effect as first calling socket_bind4 with IP address 0.0.0.0 and port 0.
socket_connect4(s,ip,p);
.SH "SEE ALSO"
socket_connect6(3)
socket_connect6(3), socket_fastopen_connect4(3)

2
socket/socket_connect6.3

@ -51,4 +51,4 @@ effect as first calling socket_bind6 with IP address :: and port 0.
socket_connect6(s,ip,p,0);
.SH "SEE ALSO"
socket_connect4(3), socket_getifname(3)
socket_connect4(3), socket_fastopen_connect6(3), socket_getifname(3)

30
socket/socket_fastopen.3

@ -0,0 +1,30 @@
.TH socket_fastopen 3
.SH NAME
socket_fastopen \- enable TCP Fast Open on a server-side TCP socket
.SH SYNTAX
.B #include <socket.h>
int \fBsocket_fastopen\fP(int \fIs\fR);
.SH DESCRIPTION
socket_fastopen enables TCP Fast Open support on a server-side TCP
socket. Call this before socket_listen(). If the platform does not
support this functionality, returns -1 and sets errno to ENOPROTOOPT (or
ENOSYS if the platform does not define ENOPROTOOPT).
Normally socket_fastopen returns 0. If anything goes wrong, socket_fastopen
returns -1, setting errno appropriately.
.SH EXAMPLE
#include <socket.h>
int \fIs\fR;
char \fIip\fR[4];
uint16 \fIp\fR;
\fIs\fR = socket_tcp4b();
socket_fastopen(s);
socket_bind4_reuse(s,ip,p);
socket_listen(16);
.SH "SEE ALSO"
socket_fastopen_connect4(3), socket_fastopen_connect6(3)

58
socket/socket_fastopen_connect4.3

@ -0,0 +1,58 @@
.TH socket_fastopen_connect4 3
.SH NAME
socket_fastopen_connect4 \- make a TCP connection and send some data
.SH SYNTAX
.B #include <socket.h>
ssize_t \fBsocket_fastopen_connect4\fP(int \fIs\fR,const char \fIip\fR[4],uint16 \fIport\fR,
const char* \fIbuf\fR,size_t \fIlen\fR);
.SH DESCRIPTION
socket_fastopen_connect4 attempts to make a connection from TCP socket \fIs\fR to
TCP port \fIport\fR on IP address \fIip\fR. If that succeeds, it
attempts to send \fIlen\fR bytes from \fIbuf\fR.
The difference to calling socket_connect4 followed by write is that, on
platforms supporting TCP Fast Open, socket_fastopen_connect4 will send
the first data packet in the third packet of the TCP handshake, saving
one useless ACK packet in network traffic.
This is only useful for protocols where the client sends the first
bytes.
socket_connect4 may return
.sp 1
.IP \(bu
>=0, to indicate that the connection succeeded and this many bytes were
sent.
.IP \(bu
-1, setting errno to error_inprogress or error_wouldblock, to indicate
that the socket is non-blocking
.IP \(bu
-1, setting errno to something else, to indicate that the connection
failed (and failed immediately, if the socket is non-blocking).
.PP
When a background connection succeeds or fails, \fIs\fR becomes
writable; you can use socket_connected to see whether the connection
succeeded. If the connection failed, socket_connected returns 0,
setting errno appropriately.
Once a TCP socket is connected, you can use the read and write
system calls to transmit data.
You can call socket_connect4 without calling socket_bind4. This has the
effect as first calling socket_bind4 with IP address 0.0.0.0 and port 0.
.SH EXAMPLE
#include <socket.h>
int \fIs\fR;
char \fIip\fR[4];
uint16 \fIp\fR;
\fIs\fR = socket_tcp4();
socket_bind4(s,ip,p);
socket_fastopen_connect4(s,ip,p,"hello",5);
.SH "SEE ALSO"
socket_connect4(3), socket_fastopen_connect6(3), socket_fastopen(3)

60
socket/socket_fastopen_connect6.3

@ -0,0 +1,60 @@
.TH socket_fastopen_connect6 3
.SH NAME
socket_fastopen_connect6 \- make a TCP connection and send some data
.SH SYNTAX
.B #include <socket.h>
ssize_t \fBsocket_fastopen_connect6\fP(int \fIs\fR,
const char \fIip\fR[16],uint16 \fIport\fR,uint32 \fIscope_id\fR,
const char* \fIbuf\fR,size_t \fIlen\fR);
.SH DESCRIPTION
socket_fastopen_connect6 attempts to make a connection from TCP socket \fIs\fR to
TCP port \fIport\fR on IP address \fIip\fR. If that succeeds, it
attempts to send \fIlen\fR bytes from \fIbuf\fR.
The difference to calling socket_connect6 followed by write is that, on
platforms supporting TCP Fast Open, socket_fastopen_connect6 will send
the first data packet in the third packet of the TCP handshake, saving
one useless ACK packet in network traffic.
This is only useful for protocols where the client sends the first
bytes.
socket_connect6 may return
.sp 1
.IP \(bu
>=0, to indicate that the connection succeeded and this many bytes were
sent.
.IP \(bu
-1, setting errno to error_inprogress or error_wouldblock, to indicate
that the socket is non-blocking
.IP \(bu
-1, setting errno to something else, to indicate that the connection
failed (and failed immediately, if the socket is non-blocking).
.PP
When a background connection succeeds or fails, \fIs\fR becomes
writable; you can use socket_connected to see whether the connection
succeeded. If the connection failed, socket_connected returns 0,
setting errno appropriately.
Once a TCP socket is connected, you can use the read and write
system calls to transmit data.
You can call socket_connect6 without calling socket_bind6. This has the
effect as first calling socket_bind6 with IP address :: and port 0.
.SH EXAMPLE
#include <socket.h>
int \fIs\fR;
char \fIip\fR[16];
uint16 \fIp\fR;
uint32 \fIscope_id\fR;
\fIs\fR = socket_tcp6b();
socket_bind6(s,ip,p);
socket_fastopen_connect6(s,ip,p,scope_id,"hello",5);
.SH "SEE ALSO"
socket_connect6(3), socket_fastopen_connect4(3), socket_fastopen(3)

38
socket/socket_quickack.3

@ -0,0 +1,38 @@
.TH socket_quickack 3
.SH NAME
socket_quickack \- turn TCP Quick ACK mode on or off
.SH SYNTAX
.B #include <socket.h>
int \fBsocket_quickack\fP(int \fIs\fR,int \fIvalue\fR);
.SH DESCRIPTION
socket_quickack switches TCP Quick ACK mode on (value=1) or off
(value=0). If the platform does not support this functionality, returns
-1 and sets errno to ENOPROTOOPT (or ENOSYS if the platform does not
define ENOPROTOOPT).
TCP Quick ACK mode is on by default because the operating system has to
assume it's an interactive connection. In that case, an ACK will be
sent quickly after data came in. If your code handles non-interactive
server connections, it may make sense to switch Quick ACK mode off,
telling the kernel to delay sending ACKs because the server is going to
respond to incoming requests anyway, so the ACK can be piggy-backed onto
that response, saving useless network traffic.
Normally socket_quickack returns 0. If anything goes wrong, socket_quickack
returns -1, setting errno appropriately.
.SH EXAMPLE
#include <socket.h>
int \fIs\fR;
char \fIip\fR[4];
uint16 \fIp\fR;
\fIs\fR = socket_tcp4b();
socket_quickack(s);
socket_bind4_reuse(s,ip,p);
socket_listen(16);
.SH "SEE ALSO"
socket_fastopen(3)

18
socket/socket_quickack.c

@ -0,0 +1,18 @@
#include "socket.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
#include <errno.h>
int socket_quickack(int s,int value) {
#ifdef TCP_QUICKACK
return setsockopt(s, SOL_TCP, TCP_QUICKACK, &value, sizeof(int));
#else
#ifdef ENOPROTOOPT
errno=ENOPROTOOPT;
#else
errno=ENOSYS;
#endif
return -1;
#endif
}

2
socket/socket_send4.3

@ -5,7 +5,7 @@ socket_send4 \- send a UDP datagram
.B #include <socket.h>
ssize_t \fBsocket_send4\fP(int \fIs\fR, const char* \fIbuf\fR, size_t \fIlen\fR,
const char \fIip\fR[4],uint16 \fIport\fR);
const char \fIip\fR[4],uint16 \fIport\fR);
.SH DESCRIPTION
socket_send4 sends \fIlen\fR bytes starting at \fIbuf\fR in a UDP
datagram over the socket \fIs\fR to UDP port \fIport\fR on IP address

8
socket/socket_send4.c

@ -8,12 +8,16 @@
#include "byte.h"
#include "socket.h"
ssize_t socket_send4(int s,const char *buf,size_t len,const char ip[4],uint16 port) {
ssize_t socket_send4_flag(int s,const char *buf,size_t len,const char ip[4],uint16 port,int flag) {
struct sockaddr_in si;
byte_zero(&si,sizeof si);
si.sin_family = AF_INET;
uint16_pack_big((char*) &si.sin_port,port);
*((uint32*)&si.sin_addr) = *((uint32*)ip);
return winsock2errno(sendto(s,buf,len,0,(void*) &si,sizeof si));
return winsock2errno(sendto(s,buf,len,flag,(void*) &si,sizeof si));
}
ssize_t socket_send4(int s,const char *buf,size_t len,const char ip[4],uint16 port) {
return socket_send4_flag(s,buf,len,ip,port,0);
}

2
socket/socket_send6.3

@ -5,7 +5,7 @@ socket_send6 \- send a UDP datagram
.B #include <socket.h>
ssize_t \fBsocket_send6\fP(int \fIs\fR, const char* \fIbuf\fR, size_t \fIlen\fR,
const char \fIip\fR[16], uint16 \fIport\fR, uint32 \fIscope_id\fR);
const char \fIip\fR[16], uint16 \fIport\fR, uint32 \fIscope_id\fR);
.SH DESCRIPTION
socket_send6 sends \fIlen\fR bytes starting at \fIbuf\fR in a UDP
datagram over the socket \fIs\fR to UDP port \fIport\fR on IP address

8
socket/socket_send6.c

@ -13,7 +13,7 @@
#include "ip4.h"
#include "havescope.h"
ssize_t socket_send6(int s,const char *buf,size_t len,const char ip[16],uint16 port,uint32 scope_id)
ssize_t socket_send6_flag(int s,const char *buf,size_t len,const char ip[16],uint16 port,uint32 scope_id,int flag)
{
#ifdef LIBC_HAS_IP6
struct sockaddr_in6 si;
@ -41,9 +41,13 @@ ssize_t socket_send6(int s,const char *buf,size_t len,const char ip[16],uint16 p
#else
si.sin6_scope_id=0;
#endif
return winsock2errno(sendto(s,buf,len,0,(void*) &si,sizeof si));
return winsock2errno(sendto(s,buf,len,flag,(void*) &si,sizeof si));
#else
errno=EPROTONOSUPPORT;
return -1;
#endif
}
ssize_t socket_send6(int s,const char *buf,size_t len,const char ip[16],uint16 port,uint32 scope_id) {
return socket_send6_flag(s,buf,len,ip,port,scope_id,0);
}
Loading…
Cancel
Save