summaryrefslogtreecommitdiff
path: root/lib/HACKING
blob: c8963246422587ff031387d3c1364e7244e2aa0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
HACKING file for libradsec (in Emacs -*- org -*- mode).

Status as of libradsec-0.2.0.dev (2013-05-06).

* Build instructions
sh autogen.sh
./configure #--enable-tls
make

examples/client -r examples/client.conf blocking-tls; echo $?

* Dependencies
Details (within parentheses) apply to Debian Wheezy.

- libconfuse (2.7-4)
  sudo apt-get install libconfuse-dev libconfuse0
- libevent2 (2.0.19-stable-3)
  sudo apt-get install libevent-dev libevent-2.0-5
- OpenSSL (1.0.1c-4) -- optional, for TLS and DTLS support
  sudo apt-get install libssl-dev libssl1.0.0
  
* Functionality and quality in 0.2.x
** Not well tested
- reading config file
- [TCP] short read
- [TCP] short write
- [TLS] basic tls support
- [TLS] preshared key support
- [TLS] verification of CN

** Known issues
- error handling when server can't bind to given listen_addr+port
- configuration of listen_addr/service is per realm
- error stack is only one entry deep
- custom allocation scheme is not used in all places

** Not implemented
- dispatch mode (planned for 0.1)
- [client] server failover / RFC3539 watchdog (planned for 0.1)
- [server] support (planned for 0.2)
- [client] TCP keepalive
- on-your-own mode
- [DTLS] support

* Found a bug?
Please report it. That is how we improve the quality of the code.

If possible, please build the library with DEBUG defined (CFLAGS="-g
-DDEBUG") and reproduce the problem. With DEBUG defined, lots of
asserts are enabled which might give a hint about what's gone wrong.

Running the library under gdb is another good idea. If you experience
a crash, catching the crash in gdb and providing a backtrace is highly
valuable for debugging.

Contact: mailto:linus+libradsec@nordu.net


* Design of the API
- There are three usage modes:

  - Application uses blocking send and receive calls (blocking
    mode). This is typically fine for a simple client.

  - Application registers callbacks with libradsec and runs the
    libevent dispatch loop (a.k.a. user dispatch mode). This would
    probably be how one would implement a server or a proxy.

  - Application runs its own event loop, using fd's for select and
    performs I/O using libradsec send/receive functions
    (a.k.a. on-your-own mode). Might be useful for an application
    which already has an event loop that wants to add RadSec
    functionality.

- Apart from configuration and error handling, an application
  shouldn't need to handle TCP and UDP connections
  differently. Similarly, the use of TLS/DTLS or not shouldn't
  influence the libradsec calls made by the application.

- Configuration is done either by using the API or by pointing at a
  configuration file which is parsed by libradsec.

- Fully reentrant.

- Application chooses allocation regime.

Note that as of 0.0.2.dev libradsec suffers from way too much focus on
the behaviour of a blocking client and is totally useless as a server.
Not only does it lack most of the functions needed for writing a
server but it also contains at least one architectural mishap which
kills the server idea -- a connection timeout (TCP) or a retransmit
timeout (UDP) will result in the event loop being broken. The same
thing will happen if there's an error on a TCP connection, f.ex. a
failing certificate validation (TLS).

* Notes on internals
** How to connect an outgoing connection?
Connecting is not done explicitly by the application but implicitly by
rs_message_send(). The application can treat connections in the same
way regardless of whether they're connection-oriented (i.e. TCP) or
not (UDP).

rs_message_send(msg)
  if msg->conn is open: mesasge_do_send(msg)
  else: 
    -> _conn_open(conn, msg)
      pick configured peer
      event_init_socket(peer)
      if TCP or TLS:
        init tcp timers
        event_init_bufferevent(conn, peer)
      else:
        init udp timers
      if not connected and not connecting:
        event_do_connect(conn)    

  if TCP:
    bufferevent_setcb()
    bufferevent_enable()
  else:
    event_assign(write_ev)         ; libevent func?
    event_add(write_ev)
  
  if not in user-dispatch-mode:
    event_base_dispatch()
** How to bind a listener and start listening for incoming connections?