Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Net app API #540

Merged
merged 8 commits into from
Jun 30, 2017
Merged

Net app API #540

merged 8 commits into from
Jun 30, 2017

Conversation

jukkar
Copy link
Member

@jukkar jukkar commented Jun 19, 2017

There has been discussion and complaints that the current net_context API that applications can use is too low level and requires lot of effort from application developer to create a bug free application. Many networking operations that various applications do, are very similar and can be provided by a library. In order to address these issues I created a higher level API that applications can use.

The API consists of two parts:

  1. Application initialization support.
  • The net_app_init() makes sure that we have IP address, routes etc. configured and the IP stack is ready to serve before continuing. User can supply a timeout to the function call, and also give a hint what kind of support it needs from the IP stack. It is possible to use only the net_app_init() without the connectivity support if needed.
  1. Connectivity support
  • Developer can create a simple TCP/UDP server or client application with only few function calls.

Example for the TCP server:

net_app_init_server(&tcp, SOCK_STREAM, IPPROTO_TCP, NULL,
		    MY_PORT, NULL, NULL, NULL);
net_app_set_cb(&tcp, NULL, tcp_received, NULL, NULL);
net_app_wait_connection(&tcp);

Example for UDP server:

net_app_init_server(&udp, SOCK_DGRAM, IPPROTO_UDP, NULL,
		    MY_PORT, NULL, NULL, NULL);
net_app_set_cb(&udp, NULL, udp_received, pkt_sent, NULL);
net_app_wait_connection(&udp);

Example TCP client:

net_app_init_client(ctx, SOCK_STREAM, IPPROTO_TCP, NULL,
		    NULL, peer, PEER_PORT, WAIT_TIME,
		    NULL, NULL, user_data);
net_app_set_cb(ctx, tcp_connected, tcp_received, NULL, NULL);
net_app_connect(ctx, CONNECT_TIME);

Example UDP client:

net_app_init_client(ctx, SOCK_DGRAM, IPPROTO_UDP, NULL,
		    NULL, peer, PEER_PORT, WAIT_TIME,
		    NULL, NULL, user_data);
net_app_set_cb(ctx, udp_connected, udp_received, NULL, NULL);
net_app_connect(ctx, CONNECT_TIME);

So the developer needs to setup the proper callbacks that will be called in various stages of the connection flow.

I created a TLS support for TCP server in this initial pull request. The TLS support is transparent to the application, all the encryption and decryption happens inside the net_app API. Only thing the application needs to do is to setup the TLS, and prepare the certificates for mbedtls library. With this transparent TLS support, it is possible to create for example MQTT over TLS support quite easily.

In order to try the TLS support, the net-tools project have this
zephyrproject-rtos/net-tools#8
PR that provides stunnel configuration so that echo-client can be run in Linux side and it can communicate with zephyr echo-server sample over TLS.

This net_app API will replace the internal net_sample_app API that was used by some of the network sample applications found under samples/net directory.

The current patchset contains these patches:

  • net_app core functions
  • conversion of echo-client and echo-server samples to use this new API
  • base TLS support
  • setting up the echo-server to use the TLS if configured so

Future plans:

  • create TLS TCP client support
  • create DTLS UDP client and server support
  • convert existing network samples to use this API

@jukkar jukkar added the net label Jun 19, 2017
@jukkar jukkar self-assigned this Jun 19, 2017
@jukkar jukkar requested review from nashif, pfalcon and tbursztyka June 19, 2017 11:35
@lpereira
Copy link
Collaborator

If we're doing this to simplify things:

  • Any reason to ask the user to specify both DGRAM/UDP or STREAM/TCP? Can't DGRAM/STREAM be inferred from the protocol?
  • I get really uneasy with functions that accepts multiple parameters of the same type; it's too easy to mix them up and difficult to know what they are from the call site. I'd prefer more functions to set each parameter rather than a single function with a lot of parameters.

Copy link
Collaborator

@tbursztyka tbursztyka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there are rooms for improving net_context API first, this current attempt of an extra layer on top of net_context is not as simple as it could

For instance:

  • net_context's callbacks. The pb with those is the stack they are ran from: net's one. We could maybe move towards using kpoll objects (actually net_context was designed long before this objects appeared)..
    It would also simplify a lot of things for the BSD socket layer I think. (it would not save or bloat memory though I think)

  • tx_slab/data_pool: I think we will need to work on smarter buffer handling, this really needs to go away at some point.

About @lpereira's comment on type/protocol, I disagree: the base function should ask for both. But starting from that idea: nothing prevents the api to expose some dedicated and simple inline function such as net_app_init_tcp_server() or net_app_init_udp_client() etc...

struct sockaddr *server_addr,
u16_t port,
net_pkt_get_slab_func_t tx_slab,
net_pkt_get_pool_func_t data_pool,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure we want to expose this tx_slab/data_pool thingy. It's very low level stuff, and in the future (hopefully) we will be able to get rid of it completely. So imo it should stay on net_context side for those who really need it, but not exposed on net_app.h

u16_t peer_port,
s32_t timeout,
net_pkt_get_slab_func_t tx_slab,
net_pkt_get_pool_func_t data_pool,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

};

/** Network application context. */
struct net_app_ctx {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A context on top of another context. Maybe simplifying net_context first would be wiser.

@GAnthony
Copy link
Collaborator

Adding this net_app_init() is a good idea to simplify the examples.

I wonder if we could go even one step further and have this initialization happen during boot-up automatically, say, during pre-application initialization?

Something like:

SYS_INIT(net_app_init(), _SYS_INIT_LEVEL_APPLICATION, ...);

perhaps its parameters can be added as Kconfig options?

That way, it will hide this common initialization from all the examples, and the function call could be completely removed from all the net (and new socket) samples.

Looking at the new BSD socket_echo.c example (#498), the only non-standard bit of code (other than the headers) keeping it from being a portable BSD socket app is that bit of Zephyr-specific initialization code (init_net()).

Hiding the initialization could be another small step to help future porting of third party BSD socket apps and protocols to Zephyr.

@pfalcon
Copy link
Contributor

pfalcon commented Jun 20, 2017

@GAnthony : Right, it's about the same idea I shared on mailing list in response to the RFC behind this patch: https://lists.zephyrproject.org/pipermail/zephyr-devel/2017-June/007799.html

@GAnthony
Copy link
Collaborator

@pfalcon: Ah, yes, thanks for pointing that out. I must have overlooked that part of the email thread. In any case, I agree it would help simplify the apps to somehow hide that initialization.

@jukkar jukkar changed the title [RFC] Net app API Net app API Jun 26, 2017
@jukkar
Copy link
Member Author

jukkar commented Jun 26, 2017

New version uploaded.
Changes:

  • added helpers for creating TCP / UDP listeners as suggested by @lpereira and @tbursztyka
  • calling net_app_init() automatically as suggested by @GAnthony and @pfalcon I made the auto init optional (it is on by default) so that application developer can call net_app_init() itself if really necessary
  • refactored the code
  • supports now both client and server roles for TLS

@jukkar jukkar force-pushed the net-app-api branch 3 times, most recently from ef9454e to 3612bf5 Compare June 27, 2017 07:25
pfalcon
pfalcon previously approved these changes Jun 27, 2017
Copy link
Contributor

@pfalcon pfalcon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

calling net_app_init() automatically as suggested by @GAnthony and @pfalcon I made the auto init optional (it is on by default) so that application developer can call net_app_init() itself if really necessary

Thanks!

Couple of possible improvements in the inline comments, but otherwise looks good.

*
* @return 0 if ok, <0 if error.
*/
int net_app_wait_connection(struct net_app_ctx *ctx);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a nitpick, but from the name or a description of this function, it's not clear whether this really waits for connection (blocks until it happens), or whether it starts to listen for connections (non-blocking). Name suggests that it really waits, though description leans towards starting to listen. If so, why not call this func e.g. net_app_listen() ?

ret = net_app_init("Initializing network", flags,
K_SECONDS(CONFIG_NET_APP_INIT_TIMEOUT));
if (ret < 0) {
NET_ERR("Network initialization failed (%d)", ret);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest to make this printk() and k_panic(), to make sure this cannot be missed, regardless of logging options.

client_or_server == MBEDTLS_SSL_IS_CLIENT ? "client" :
"server");

exit:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably need to call mbedtls_ssl_free(), mbedtls_ssl_config_free(), mbedtls_ctr_drbg_free(), and mbedtls_entropy_free() if something goes wrong.

@jukkar
Copy link
Member Author

jukkar commented Jun 28, 2017

Sent a new version. Changes:

  • net_app_wait_connection() renamed to net_app_listen()
  • changed the net_app_init() failure to print using printk() (using k_panic() seemed like overkill atm)
  • added mbedtls resource cleaning if TLS init fails

jukkar added 8 commits June 28, 2017 20:02
The network application API is a higher level API for creating
client and server type applications. Instead of applications
dealing with low level details, the network application API
provides services that most of the applications can use directly.

This commit removes the internal net_sample_*() API and converts
the existing users of it to use the new net_app API.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit will convert echo-server to use the net app API
when creating the listening service. Most of the network
setup code will be removed from echo-server by this commit.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit will convert echo-client to use the net app API
when creating the connection to peer. Most of the network
setup code will be removed from echo-client by this commit.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Removing CONFIG_NET_APP_SETTINGS from prj.conf file as the
sample does not use or need any IP addresses.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
As the net app API is automatically initialized, there is no
need to call net_app_init() by the http client and server sample
applications.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Next two commits will increase the mbedtls ram usage a bit and
https client and server sample test will fail.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Add Kconfig option that can be used to enable various debug
options in mbedtls config file.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This changes increases content buffer length
MBEDTLS_SSL_MAX_CONTENT_LEN to 1500 bytes so that we can use
this config for echo-client and echo-server network sample
applications which need to send bigger data than 1024 bytes.

Removing MBEDTLS_PEM_PARSE_C as we do not have any cert in PEM
format.

Place various MBEDTLS debug options behind CONFIG_MBEDTLS_DEBUG
Kconfig option which was introduced in previous commit.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
@jukkar
Copy link
Member Author

jukkar commented Jun 28, 2017

Getting past shippable seems to be tricky for this PR. I sent a new version:

  • increased RAM size for https_client running in qemu
  • changed back to NET_ERR() for net_app_init() as using printk() caused build errors, we can fix this later if really needed

@jukkar jukkar requested a review from Vudentz June 30, 2017 09:03
@nashif nashif merged commit a5898da into zephyrproject-rtos:master Jun 30, 2017
nagineni pushed a commit to nagineni/zephyr that referenced this pull request Nov 20, 2017
)

- Documentation said that UART could use tty1, which was not true
   and would cause an error to be thrown. The error will still be
   thrown, but the docs now only mention tty0.

Signed-off-by: James Prestwood <james.prestwood@intel.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants