A sendfile(2) extension module for transfering a socket to a socket.

What is this for?

This module is a sendfile(2)'s extension module which supports a transfer from a stream socket to a stream socket. It is not bi-directional. The implementation of transfering a socket to a socket is "zero-copy", meaning that it has been optimized so that copying of the socket data is avoided. Currently, this module supports only TCP and tested.

I think this module is useful when you have a plan to make a proxy server.

Features

Download

How to install

  $ wget http://weongyo.org/project/freebsd/sendsock/sendsock-0.1.tar.gz
  $ tar xzf sendsock-0.1.tar.gz
  $ cd sendsock-0.1
  $ make
  $ su - root
  # make load
  # make unload

How to use

The spec of sendfile(2) for transfering a socket to a socket is same with original sendfile(2) and supports the sendfile(2)'s functionality perfectly. The differences are like below.
  1. The extension will work ONLY when the value of `flags' which is the seventh argument of sendfile(2) is set with SF_SENDSOCK(0x4). Otherwise, the operation of sendfile(2) will be same with the origin.
  2. `fd' which is the first argument of sendfile(2) can be a socket descriptor if the value of `flags' which is the seventh argument of sendfile(2) is SF_SENDSOCK(0x4).
  3. `offset' which is the third argument of sendfile(2) always MUST be zero.
  4. `nbytes' which is the fourth argument of sendfile(2) can be 0 or a number which is larger than 0. If the value is 0, sendfile(2) will transfer the data until a connection which is one of the connection is closed or aborted.
  5. After the transfer, sendfile(2) don't drop the connection if SF_SENDSOCK(0x4) is set.
For details for use, see a example source.

How to test

  (In Sever # 1)
  $ nc -l 9999

  (In Reply Server # 2)
  $ cd sendsock-0.1
  $ make -f Makefile.4test
  $ ./test_sendsock -t (server #1 ip) -p 9999 -l 10000

  (In Client # 3)
  $ nc (relay server #2) 10000 < filename

The benchmark results

The benchmark test is based on the test above. The results are as follows:

Result #1: a TCP socket to a TCP socket

I transfered 1G bytes from a TCP socket to a TCP socket using the sendfile(2) extension module or the normal implementation which uses recv(2)/send(2).
$ ./ministat -w 73 -c 99.5 1000m_real_sendsock 1000m_real_rcvsnd 
x 1000m_real_sendsock
+ 1000m_real_rcvsnd
+-------------------------------------------------------------------------+
|x      x      x  xx*x     * +*x    + +x      ++   +       +             +|
|         |_________MA____|_____|_____M___A______________|                |
+-------------------------------------------------------------------------+
    N           Min           Max        Median           Avg        Stddev
x  11       129.455       136.535        133.02     133.13645     2.0092308
+  11       133.047       142.791       136.374     136.97273     2.8720608
Difference at 99.5% confidence
        3.83627 +/- 3.75385
        2.88146% +/- 2.81955%
        (Student's t, pooled s = 2.47848)
I transfered 100M bytes.
$ ./ministat -w 73 -c 99.5 100m_real_sendsock 100m_real_rcvsnd 
x 100m_real_sendsock
+ 100m_real_rcvsnd
+-------------------------------------------------------------------------+
|                                                                       + |
|                                                                       + |
|x xx       x   x                                              +    +   + |
||__M__A______|                                                   |__A__M||
+-------------------------------------------------------------------------+
    N           Min           Max        Median           Avg        Stddev
x   5         4.687         4.769           4.7        4.7198   0.035351096
+   5         5.028         5.074         5.073        5.0602   0.020042455
Difference at 99.5% confidence
        0.3404 +/- 0.0817631
        7.21217% +/- 1.73234%
        (Student's t, pooled s = 0.028735)

Thanks to

feedback

Last updated: 2007.05.28 Weongyo Jeong