todo: update item about proxy handling
[NetworkManager.git] / TODO
1 So you're interested in hacking on NetworkManager?  Here's some cool
2 stuff you could do...
3
4 * Internet Connectivity Detection Enhancements
5
6 Current connectivity checking is global, while what we really want is to check
7 connectivity per-interface and update the global state based on the composite
8 of each device's state.  Unfortunately that requires two things:
9
10 1) latest libsoup and glib for using libsoup connection state signals, which
11    allow us to set socket options before the actual connection is made; here
12    we'd bind the socket to the specific IP address of the interface we're
13    using, and possibly set SO_BINDTODEVICE as well
14 2) setting /proc/sys/net/ipv4/conf/<iface>/rp_filter to "2" which tells the
15    kernel to route the incoming and outgoing packet properly even though the
16    interface may not have the necessary routes
17
18 The first is the largest obstacle, but ideally we implement this and enable it
19 when we have the required glib and libsoup versions available.  One other
20 complication is that this checking should be done during the
21 NM_DEVICE_STATE_IP_CHECK phase (along with other operations like WiFi hotspot
22 auto-login) while the current checks are done globally in nm-manager.c, so 
23 keeping both code paths might be complex.
24
25 But ideally, once the device has successfully gotten an IPv4 or IPv6 address, it
26 should enter the state NM_DEVICE_STATE_IP_CHECK, where a connectivity check is
27 started.  After the check returns, the device would set a property in
28 NMDevicePrivate to indicate whether Internet access was successful or not, and
29 advance to the NM_DEVICE_STATE_ACTIVATED state.
30
31 The NMManager object, when determining the overall NM_STATE_* state in the
32 nm_manager_update_state() function, would query this property and set
33 NM_STATE_CONNECTED_LOCAL, NM_STATE_CONNECTED_SITE, or NM_STATE_CONNECTED_GLOBAL
34 based on it and the device's state.
35
36
37 * Implement NM_DEVICE_STATE_DISCONNECTING
38
39 To allow for "pre-down" scenarios, this state should be implemented before a
40 device is taken down while it still has connectivity.  If the device is
41 taken down because it's ethernet carrier was dropped, or because the WiFi
42 connection was terminated by the supplicant, this state is pointless and should
43 be skipped.  But if the user requested a manual "disconnect", or NM is dropping
44 connections on exit, etc, then this state should be entered.  In the future
45 this state should hook into a new dispatcher action in src/NetworkManagerUtils.c
46 to exectue dispatcher scripts during the disconnection, and to wait a limited
47 amount of time for each script to complete before allowing the device to
48 proceed to the NM_DEVICE_STATE_DISCONNECTED state, fully implementing pre-down.
49
50
51 * Ethernet Network Auto-detection
52
53 There are various methods we can use to autodetect which wired network connection
54 to use if the user connects to more than one wired network on a frequent basis.
55 First, 802.1x enterprise switches broadcast frames which can be used to indicate
56 that the switch supports 802.1x and thus allow NetworkManager to select an
57 802.1x connection instead of blindly trying DHCP.  Second, NetworkManager could
58 listen for traffic from a list of MAC addresses.  Third, NetworkManager could
59 integrate 'arping' functionality to determine if a given IP address matches a
60 given MAC address, and thus automatically select that connection.  All these
61 methods can co-exist and be used in parallel.
62
63 One small caveat is that MAC addresses are trivial to spoof, so just because
64 NetworkManager has discovered a certain MAC address does not mean the network
65 is authenticated; only 802.1x security can assure that a network is the network
66 the user expects it to be.
67
68 In any case, a new 'anchor-addresses' property of type string-array should be
69 added to the NMSettingWired setting.  Each string element of this property
70 should be of the format "<ip>/<mac>" or simply "<mac>".  The first format with
71 an IP address would indicate that "arping"-type behavior should be used to
72 actively detect the given MAC address; obviously if the given MAC address is
73 used for passive discovery as well.  The second format simply lists a MAC
74 address to passively listen for.
75
76 One drawback of listening or probing for known MAC addresses is an increase in
77 latency during connections to ethernet networks.  The probing/listening delay
78 should be a reasonable amount of time, like 4 - 5 seconds or so, and should
79 only be used when a visible connection has anchor addresses.
80
81 Next a gboolean 'anchor-probing' variable should be added to the
82 NMDeviceEthernetPrivate structure in src/nm-device-ethernet.c.  This variable
83 should be set to TRUE whenever the device's carrier turns on *and* there are
84 visible NMConnections with anchor addresses (ie, connections which are system-
85 wide or where one of the allowed users of that connection is logged in).  Then
86 probing and listening are started, which involves opening a low-level socket
87 on the interface and starting the arping run or listening for MAC addresses.
88 A timer is also started (don't forget to cache the timer's source ID in the
89 NMDeviceEthernetPrivate data, and to cancel the timer whenever the device
90 transitions to any state other than DISCONNECTED).
91
92 If a known MAC address is discovered as a result of probing or listening, the
93 probe/listen socket, timeout, and data are cleaned up, and NetworkManager
94 would begin activation of the NMConnection that specified the found MAC address
95 in the 'anchor-addresses' property.  If two or more connections specify the
96 same MAC address, the connection with the most recent timestamp should be
97 preferred.
98
99 Similarly, if the probing/listening process detects 802.1x frames the device
100 should be marked as requring 802.1x authentication until the carrier drops.
101 This would be accomplished by adding a new property to the NMDeviceEthernet
102 object and exporting that property through the
103 introspection/nm-device-ethernet.xml file.  This would allow clients like
104 applets to ensure that users are aware that the device will not allow
105 un-authenticated connections and that additional credentials are required to
106 successfully connect to this network.
107
108
109 * VPN re-connect (bgo #349151)
110
111 NM should remember whether a VPN was connected if a connection disconnects
112 (like WiFi drops out or short carrier drop) or if the laptop goes to sleep.
113 Upon reconnect, if the same Connection is again active, the previously
114 connected VPN should be activated again as well.  Basically, don't just drop
115 the VPN because WiFi choked for 10 seconds, but reconnect the VPN if it was
116 connected before the drop.
117
118
119 * VPN and IPv6
120
121 The internal VPN capability should support IPv6.  Essentially, the D-Bus
122 interface between NetworkManager and the VPN service daemons should be extended
123 with an IP6Config signal that passes up the IPv6 addressing and routing details
124 if the VPN daemon is IPv6 capable.  NM should then process those details like it
125 does with IPv4.  include/NetworkManagerVPN.h should be updated with key/value
126 pairs defining the various IPv6 attributes much like the IPv4 ones are defined.
127
128
129 * VPN IP Methods
130
131 Some VPNs (openvpn with TAP for example) require that DHCP is run on a
132 pseudo-ethernet device to obtain addressing information.  This is not currently
133 possible, but NM already has all the code for DHCP.  Thus, a new "method"
134 key should be defined in include/NetworkManagerVPN.h to allow for DHCP to
135 be performed if the VPN service daemon requests it in the IP4Config or IP6Config
136 signals.  A patch here:
137
138 http://cgit.freedesktop.org/NetworkManager/NetworkManager/commit/?h=vpn-ip-method
139
140 shows that.  In nm-vpn-connection.c, upon receipt of the D-Bus Ip4Config signal
141 from the VPN plugin, NetworkManager would inspect the "method" property of the
142 ip4 config dictionary.  If that property was present and set to "auto" then
143 DHCP would be started using the network interface returned in the dict.  The
144 nm_vpn_connection_ip4_config_get() function should be split up into two
145 functions, one containing the existing code for static configuration, and a
146 second for handling DHCP kickoff.  Minimal parsing of the response should be
147 handled in the newly reduced nm_vpn_connection_ip4_config_get() function.
148
149 To handle DHCP, the NMVPNConnectionPrivate structure should have two members
150 added:
151
152     NMDHCPManager *dhcp_manager;
153     NMDHCPClient  *dhcp4_client;
154
155 which would be initialized in the new DHCP handler code split off from
156 nm_vpn_connection_ip4_config_get().  These new members would be disposed of in
157 both vpn_cleanup() and dispose(), though remember to stop any ongoing DHCP
158 transaction when doing so (see dhcp4_cleanup() in nm-device.c for example code).
159 For basic code to start the DHCP transaction, see dhcp4_start() in nm-device.c
160 as well.  After calling nm_dhcp_manager_start_ip4() and connecting the signals
161 to monitor success and failure, the VPN IP4 config handler would simply return
162 without changing VPN state, unless a failure occurred.
163
164 Then, when the DHCP transaction succeeds, which we'd know by checking the
165 DHCP client state changes in the "state-changed" signal handler we attached to
166 the DHCP client object returned from nm_dhcp_manager_start_ip4(), the code
167 would retrieve the completed NMIP4Config object from the DHCP client using the
168 nm_dhcp_client_get_ip4_config() function, and then proceed to execute
169 essentially the bottom-half of the existing nm_vpn_connection_ip4_config_get()
170 function to merge that config with user overrides and apply it to the VPN
171 tunnel interface.  Other state changes from the DHCP client might trigger a
172 failure of the VPN connection, just like DHCP timeouts and lease-renewal
173 failures do for other devices (see dhcp_state_changed() in nm-device.c).
174
175
176 * VPN Service Daemon Secret Requests
177
178 In addition to NM asking the service daemons whether more secrets are required,
179 VPN service daemons (like nm-vpnc-service, nm-openvpn-service, etc) should be
180 able to ask NetworkManager to provide secrets during the connection attempt. To
181 do this, the plugin should advertise its ability to handle out-of-band secrets
182 in its .service file via the key 'async-secrets=true'.  NetworkManager would
183 check that key and if present activate the VPN as normal, but skip the explicit
184 NeedSecrets calls.
185
186 Instead, a new "SecretsRequired" signal would be added to
187 introspection/nm-vpn-plugin.xml (and corresponding helper code added to
188 libnm-glib/nm-vpn-plugin.c) that would be emitted when the plugin determined
189 that secrets were required.  This signal would have D-Bus signature of "sas"
190 for the arguments [ <s:uuid>, <as:secrets> ] with the <uuid> obviously being
191 the connection UUID, and <secrets> being an array of strings of plugin-specific
192 strings the plugin requires secrets for.  This array of strings would then be
193 passed as the "hints" parameter in nm-vpn-connection.c when secrets are
194 requested from agents in a subsequent nm_settings_connection_get_secrets() call.
195 At this time the agent code only allows one hint per request, so we may need to
196 extend that to allow more than one hint.
197
198 Thus when connecting if the plugin supported async secrets NetworkManager would
199 still request existing secrets (without interactivity) and send them to the
200 VPN service daemon in the Connect D-Bus method, then wait for the service daemon
201 to either request secrets asynchronously via the SecretsRequired signal or to
202 signal successful connection via the Ip4Config signal.
203
204 The vpnc plugin would need to be reworked to open a pipe to vpnc's stdout and
205 stdin file descriptors to capture any authentication messages, and to match
206 these messages to known secrets request strings.  When receiving one of these
207 strings the plugin would determine which secret was being requested and then
208 emit the SecretsRequired signal to NetworkManager.  This would also imply that
209 nm-vpnc-service exectutes vpnc with the "--xauth-inter" argument to enable
210 challenge-response and does not use the "--non-inter" flag which suppresses that
211 behavior.
212
213
214 * WPS
215
216 wpa_supplicant has support for WPS (Wifi Protected Setup, basically Bluetooth-
217 like PIN codes for setting up a wifi connection) and we should add support for
218 this to NetworkManager too.  APs that support WPS will say so in their beacon
219 IEs which are contained in the "WPA" and "RSN" properties of the BSS object
220 exported by the supplicant, and can be processed in src/nm-wifi-ap.c's
221 foreach_property_cb() function.  We should add some private fields to the
222 NMAccessPoint object (defined in nm-wifi-ap.c) to remember whether a specific
223 AP supports WPS and what WPS methods it supports, and expose that over D-Bus to
224 GUI clients as well.
225
226 There are two common WPS setup methods: PIN and button.  For PIN, the router
227 either displays a random PIN on an LCD or the router's web UI, or a static PIN
228 is printed on the router itself.  The user enters that PIN instead of a PSK
229 when connecting.  For the "button" method, the router has a physical button that
230 when pushed, allows any client to connect for a short period of time.
231
232 We'll then need to add some properties to the NMSettingWirelessSecurity setting
233 for the WPS PIN code so that when the user enters it through the GUI, it can
234 be passed back to NM.  And we'll need to figure out some mechanism for passing
235 back an indication that the user pushed the button on the router for the
236 pushbutton method.
237
238 When connecting to a new access point that supports WPS, the GUI client would
239 call the AddAndActivateConnection method and wait for NM to request secrets.
240 NM would determine that the AP supports WPS, and request WPS secrets from the
241 applet.  The applet would ask the user for a PIN, or to push the button on the
242 AP, instead of asking for a passphrase or PSK.  When the user has entered the
243 PIN or pushed the button, the applet returns this information to NM, which
244 proceeds with the connection.
245
246 NM sends the correct wpa_supplicant config for WPS to the supplicant, and waits
247 for the connection to occur.  WPS can only be used the *first* time, so after a
248 first successfull connection, NM must request the actual hexadecimal PSK from 
249 wpa_supplicant via D-Bus, and store that PSK in the connection, clear any WPS
250 PIN code from the connection, and save the connection to backing storage.
251
252 Any applet GUI should also allow the user to enter the PSK instead of completing
253 association using WPS, since quite a few routers out there are broken, or
254 because the user has no physical access to the router itself, but has been given
255 as passphrase/PSK instead.
256
257
258 * Proxies
259
260 HTTP and other proxies are per-connection configuration.  It's highly unlikely
261 that the same proxy you need to use at work is used at home or in a coffee shop.
262 Thus, it makes sense that which proxy settings to use should be updated when
263 network connections change.  NetworkManager is a perfect place to do this since
264 it tracks which network connections are active, and it already queries the
265 network for automatic proxy configuration via DHCP and WPAD.
266
267 However, proxy handling is complicated and may require use of Javascript to
268 parse PAC files provided by WPAD, and this is not something NetworkManager
269 should do itself.  Instead, that should be left to "proxy handlers", or external
270 utilities like libproxy or pacrunner that take raw proxy information, parse it,
271 and tell applications what proxy server to use for a specific network resource.
272 NetworkManager should provide all the proxy information it can find to these
273 external proxy handlers via the D-Bus interface and dispatcher scripts.
274
275 We should add a new NMSetting subclass called NMSettingProxy that holds
276 necessary proxy configuration.  The properties of this setting should be a
277 superset of what is provided in the Firefox proxy configuration screen and the
278 various desktop environment proxy configuration tools like the GNOME Network
279 Proxy control panel; this should include at a minimum:
280
281   method: "auto", "manual", "none"
282   default-proxy: string
283   default-proxy-port: uint
284   default-always: boolean (use default proxy for all protocols)
285   ssl-proxy: string
286   ssl-proxy-port: uint
287   ftp-proxy: string
288   ftp-proxy-port: uint
289   socks-proxy: string
290   socks-proxy-port: uint
291   socks-version: uint, either 4 or 5
292   no-proxy-for: array of strings (things not to use the proxy for, ie ".foobar.com",
293                  "192.168.0.1/24", an IPv6 address, etc)
294   pac-url: string (URL of PAC file, overrides DHCP-provided WPAD value)
295   (FIXME: proxy authentication?  do we need separate user/pass properties for
296     each protocol type?  should NM handle proxy auth or should it be punted
297     to each application?)
298
299 After completing IP configuration but still during the NM_DEVICE_STATE_IP_CONFIG
300 activation stage, NetworkManager would merge the automatically supplied proxy
301 configuration (from DHCP's WPAD option) with user-provided overrides from the
302 NMSettingProxy export the resulting proxy configuration via D-Bus and dispatcher
303 scripts.  The 'default' connection's proxy configuration would be preferred, so
304 we'd have to update proxy configuration from nm-policy.c the same time we update
305 DNS information and the default route.
306
307 Merged proxy information should be exposed in two places.  First, it should be
308 exported over D-Bus as a property of the org.freedesktop.NetworkManager.Device
309 interface.  This property should be named "ProxyInfo" and should have the
310 D-Bus signature "a{sv}" (eg, dictionary) and should mirror the properties from
311 the NMSettingProxy object.
312
313 Second, it should be exported via the dispatcher to dispatcher scripts when
314 with the "up" and "down" events.
315
316
317 * Better Tablet/Mobile Behavior
318
319 There are a few components to this:
320
321 1) kernel driver and hardware capabilities: most mobile devices use periodic
322 background scanning to quickly determine whether a known SSID is available and
323 notify the connection manager to connect to it.  This typically requires special
324 capabilities and good powersave/sleep support from the WiFi kernel driver.
325 There is a background scanning API in nl80211, but we need to determine how many
326 SSIDs each driver allows for background scanning, and based on that number, give
327 the driver the most recent N SSIDs.  We still need to periodically wake the
328 device up and do a full scan just in case the user is near a known SSID that was
329 not in the N top recently used networks.  This is also beneficial to normal
330 desktop use-cases.
331
332 wpa_supplicant doesn't currently provide an explicit interface for sending SSIDs
333 to the driver for background scanning, but could simply send a list using
334 configured networks.  However, NM currently does not send *all* configured
335 connections' SSIDs to the supplicant, so that's something we should do first
336 to optimize connection times.  To do this, NM would need to order all networks
337 using the NM timestamp and convert that into a supplicant priority number, which
338 would need to be adjusted periodically when the timestamp was updated.  This
339 would involve tracking each network (exposed by the supplicant as a D-Bus
340 object) and making sure they were added, deleted, and updated when the backing
341 NMConnection objects changed.  One complication is that the supplicant
342 requires secrets for various network types when the network is added via D-Bus,
343 and NetworkManager might not have those secrets yet.  We may need to modify
344 the supplicant allow for *all* secrets (PSKs, WEP keys, etc) to be requested
345 on-demand, not just EAP secrets like 802.1x passwords.  We then need to fix
346 up the supplicant's D-Bus interface to actually send requests for secrets out
347 over D-Bus (like wpa_supplicant_eap_param_needed() does for the socket-based
348 control interface) and to handle the resulting reply from a D-Bus client like
349 wpa_supplicant_ctrl_iface_ctrl_rsp() does.
350
351 With the secrets request stuff and priority handling in place, wpa_supplicant
352 would control network selection and roaming (based on the priorities NM gave it
353 of course) instead of NetworkManager itself, and hopefully lead to a faster WiFi
354 connection process.
355
356 2) single-device-at-a-time with overlapping connections: this is also probably
357 the best route to go for desktop use-cases as well.  Instead of bringing all
358 available connections up, only bring up the "best" connection at any given
359 time based on the current priority list (which is rougly Ethernet > WiFi >
360 3G/Bluetooth/WiMAX).  However, to ensure seamless connectivity, when one
361 connection begins to degrade, the next-best connection should be started before
362 the current one is terminated, such that there is a small amount of overlap.
363 Consequently the same behavior should be used when a better connection becomes
364 available.  This behavior should be suspended when special connections like
365 Internet Connection Sharing ones are started, where clearly the priorities
366 are different (ie, for Mobile Hotspot 3G > WiFi).