X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=dccp_send.c;h=53fa54e3fbac6fca71ea6005c10a6fa2e707dd3f;hp=b13f719ecf6e4ce0c9e245ce4fd49e74c6fe95d1;hb=53077ea78f01e197e84529ae42558af5c3a68429;hpb=f099900540c4e4c54b10181254b895ccfe6ef410 diff --git a/dccp_send.c b/dccp_send.c index b13f719e..53fa54e3 100644 --- a/dccp_send.c +++ b/dccp_send.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2010 Andre Noll + * Copyright (C) 2006-2011 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ @@ -13,7 +13,6 @@ #include #include -#include #include #include "para.h" @@ -25,6 +24,7 @@ #include "net.h" #include "list.h" #include "send.h" +#include "sched.h" #include "vss.h" #include "fd.h" #include "close_on_fork.h" @@ -32,17 +32,11 @@ #include "server.cmdline.h" #include "acl.h" -/** Do not write more than that many bytes at once. */ -#define DCCP_MAX_BYTES_PER_WRITE 1024 - static struct sender_status dccp_sender_status, *dss = &dccp_sender_status; -static struct sender *self; - struct dccp_fec_client { struct fec_client_parms fcp; struct fec_client *fc; - struct sender_client *sc; }; static void dccp_pre_select(int *max_fileno, fd_set *rfds, @@ -89,24 +83,31 @@ static void dccp_shutdown_clients(void) dccp_shutdown_client(sc); } -static int dccp_open(void *client, struct fec_client_parms **fcp) +/** * Obtain current MPS according to RFC 4340, sec. 14. */ +static int dccp_init_fec(struct sender_client *sc) { - struct dccp_fec_client *dfc = client; - - dfc->fcp.slices_per_group = 4; - dfc->fcp.data_slices_per_group = 3; - dfc->fcp.max_slice_bytes = 1472; - *fcp = &dfc->fcp; - return 1; + int mps, ret; + socklen_t ml = sizeof(mps); + + /* If call fails, return some sensible minimum value */ + ret = getsockopt(sc->fd, SOL_DCCP, DCCP_SOCKOPT_GET_CUR_MPS, &mps, &ml); + if (ret < 0) { + PARA_NOTICE_LOG("can not determine MPS: %s\n", strerror(errno)); + mps = generic_max_transport_msg_size(sc->fd) - DCCP_MAX_HEADER; + } + PARA_INFO_LOG("current MPS = %d bytes\n", mps); + assert(mps > 0); + if (conf.dccp_max_slice_size_arg > 0) + mps = PARA_MIN(mps, conf.dccp_max_slice_size_arg); + return mps; } -static int dccp_send_fec(char *buf, size_t len, void *private_data) +static int dccp_send_fec(struct sender_client *sc, char *buf, size_t len) { - struct dccp_fec_client *dfc = private_data; - int ret = write_nonblock(dfc->sc->fd, buf, len, DCCP_MAX_BYTES_PER_WRITE); + int ret = write_nonblock(sc->fd, buf, len); if (ret < 0) - dccp_shutdown_client(dfc->sc); + dccp_shutdown_client(sc); return ret; } @@ -140,8 +141,12 @@ static void dccp_post_select(fd_set *rfds, __a_unused fd_set *wfds) } dfc = para_calloc(sizeof(*dfc)); sc->private_data = dfc; - dfc->sc = sc; - /* XXX RESOLVED LATER vss_add_fec_client(self, dfc, &dfc->fc); */ + dfc->fcp.data_slices_per_group = conf.dccp_data_slices_per_group_arg; + dfc->fcp.slices_per_group = conf.dccp_slices_per_group_arg; + dfc->fcp.init_fec = dccp_init_fec; + dfc->fcp.send_fec = dccp_send_fec; + dfc->fcp.need_periodic_header = false; + dfc->fc = vss_add_fec_client(sc, &dfc->fcp); } static int dccp_com_on(__a_unused struct sender_command_data *scd) @@ -151,6 +156,7 @@ static int dccp_com_on(__a_unused struct sender_command_data *scd) static int dccp_com_off(__a_unused struct sender_command_data *scd) { + dccp_shutdown_clients(); generic_com_off(dss); return 1; } @@ -208,15 +214,14 @@ static char *dccp_info(void) */ void dccp_send_init(struct sender *s) { - int ret; + int ret, k, n; s->info = dccp_info; s->send = NULL; - s->open = dccp_open; - s->send_fec = dccp_send_fec; s->pre_select = dccp_pre_select; s->post_select = dccp_post_select; s->shutdown_clients = dccp_shutdown_clients; + s->resolve_target = NULL; s->help = generic_sender_help; s->client_cmds[SENDER_ON] = dccp_com_on; s->client_cmds[SENDER_OFF] = dccp_com_off; @@ -225,11 +230,19 @@ void dccp_send_init(struct sender *s) s->client_cmds[SENDER_ADD] = NULL; s->client_cmds[SENDER_DELETE] = NULL; + k = conf.dccp_data_slices_per_group_arg; + n = conf.dccp_slices_per_group_arg; + + if (k <= 0 || n <= 0 || k >= n) { + PARA_WARNING_LOG("invalid FEC parameters, using defaults\n"); + conf.dccp_data_slices_per_group_arg = 3; + conf.dccp_slices_per_group_arg = 4; + } + init_sender_status(dss, conf.dccp_access_arg, conf.dccp_access_given, conf.dccp_port_arg, conf.dccp_max_clients_arg, conf.dccp_default_deny_given); ret = generic_com_on(dss, IPPROTO_DCCP); if (ret < 0) PARA_ERROR_LOG("%s\n", para_strerror(-ret)); - self = s; }