diff options
author | Harald Welte <laforge@gnumonks.org> | 2019-03-31 15:00:00 +0200 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2019-03-31 15:00:00 +0200 |
commit | 4c37f6604863ea8cbdd2c8f9b05d028cf2ea2d46 (patch) | |
tree | 01f1d18bf77e7f301875455d27347df891640296 | |
parent | a8b86ceff2c05a623b23428da4974490ec9c15ef (diff) |
rspro_server: Configure client's bankd parameters (nr/slot/ip/port)
Change-Id: I821d0b2ba4390b9772097ddd3d610ba2c9393399
-rw-r--r-- | src/server/rspro_server.c | 109 | ||||
-rw-r--r-- | src/server/rspro_server.h | 6 |
2 files changed, 104 insertions, 11 deletions
diff --git a/src/server/rspro_server.c b/src/server/rspro_server.c index b2bcb79..9a797e1 100644 --- a/src/server/rspro_server.c +++ b/src/server/rspro_server.c @@ -88,6 +88,7 @@ enum remsim_server_client_event { CLNTC_E_REMOVE_MAP_RES, /* RemoveMappingRes received */ CLNTC_E_CONFIG_CL_RES, /* ConfigClientRes received */ CLNTC_E_PUSH, /* drain maps_new or maps_delreq */ + CLNTC_E_CL_CFG_BANKD, /* send [new] ConfigConfigBankReq */ }; static const struct value_string server_client_event_names[] = { @@ -100,6 +101,7 @@ static const struct value_string server_client_event_names[] = { OSMO_VALUE_STRING(CLNTC_E_REMOVE_MAP_RES), OSMO_VALUE_STRING(CLNTC_E_CONFIG_CL_RES), OSMO_VALUE_STRING(CLNTC_E_PUSH), + OSMO_VALUE_STRING(CLNTC_E_CL_CFG_BANKD), { 0, NULL } }; @@ -131,6 +133,13 @@ static void clnt_st_established(struct osmo_fsm_inst *fi, uint32_t event, void * LOGPFSM(fi, "ConnectClientReq from identity != Client ?!?\n"); osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL); } + + /* reparent us from srv->connections to srv->clients */ + pthread_rwlock_wrlock(&conn->srv->rwlock); + llist_del(&conn->list); + llist_add_tail(&conn->list, &conn->srv->clients); + pthread_rwlock_unlock(&conn->srv->rwlock); + if (!cclreq->clientSlot) { #if 0 /* FIXME: determine ClientID */ @@ -156,12 +165,6 @@ static void clnt_st_established(struct osmo_fsm_inst *fi, uint32_t event, void * client_conn_send(conn, resp); osmo_fsm_inst_state_chg(fi, CLNTC_ST_CONNECTED_CLIENT, 0, 0); } - - /* reparent us from srv->connections to srv->clients */ - pthread_rwlock_wrlock(&conn->srv->rwlock); - llist_del(&conn->list); - llist_add_tail(&conn->list, &conn->srv->clients); - pthread_rwlock_unlock(&conn->srv->rwlock); break; case CLNTC_E_BANK_CONN: cbreq = &pdu->msg.choice.connectBankReq; @@ -208,10 +211,86 @@ static void clnt_st_wait_cl_conf_res(struct osmo_fsm_inst *fi, uint32_t event, v } } +/*! find a connected client (if any) for given slotmap and update its Bankd configuration. + * \param[in] map slotmap whose client connection shall be updated + * \param[in] srv rspro_server on which we operate + * \param[in] bankd_conn bankd connection serving the map (may be NULL if not known) + */ +static void _update_client_for_slotmap(struct slot_mapping *map, struct rspro_server *srv, + struct rspro_client_conn *bankd_conn) +{ + struct rspro_client_conn *conn = client_conn_by_slot(srv, &map->client); + char ip_str[INET6_ADDRSTRLEN]; + char port_str[6]; + uint32_t bankd_ip; + int bankd_port; + bool changed = false; + int rc; + + OSMO_ASSERT(map); + OSMO_ASSERT(srv); + + if (!conn) + LOGP(DMAIN, LOGL_DEBUG, "%s\n", __func__); + else + LOGPFSM(conn->fi, "%s\n", __func__); + + if (!conn) + return; + + if (!bank_slot_equals(&conn->client.bankd.slot, &map->bank)) { + LOGPFSM(conn->fi, "BankSlot has changed B%u:%u -> B%u:%u\n", + conn->client.bankd.slot.bank_id, conn->client.bankd.slot.slot_nr, + map->bank.bank_id, map->bank.slot_nr); + conn->client.bankd.slot = map->bank; + changed = true; + } + + /* if caller didn't provide bankd_conn, resolve it from map */ + if (!bankd_conn) + bankd_conn = bankd_conn_by_id(srv, map->bank.bank_id); + if (!bankd_conn) + return; + + /* obtain IP and port of bankd */ + rc = osmo_sock_get_ip_and_port(bankd_conn->peer->ofd.fd, ip_str, sizeof(ip_str), + port_str, sizeof(port_str), false); + if (rc < 0) { + LOGPFSM(bankd_conn->fi, "Error during getpeername\n"); + return; + } + bankd_ip = ntohl(inet_addr(ip_str)); + bankd_port = 9999; /* TODO: configurable */ + if (conn->client.bankd.port != bankd_port || conn->client.bankd.ip != bankd_ip) { + LOGPFSM(conn->fi, "Bankd IP/Port changed to %s:%s\n", ip_str, port_str); + conn->client.bankd.ip = bankd_ip; + conn->client.bankd.port = bankd_port; + changed = true; + } + + /* update the client with new bankd information, if any changes were made */ + if (changed) + osmo_fsm_inst_dispatch(conn->fi, CLNTC_E_CL_CFG_BANKD, NULL); +} + static void clnt_st_connected_client_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) { -#if 0 struct rspro_client_conn *conn = fi->priv; + struct slotmaps *slotmaps = conn->srv->slotmaps; + struct slot_mapping *map; + + LOGPFSM(fi, "%s\n", __func__); + + /* check for an existing slotmap for this client/slot */ + slotmaps_rdlock(slotmaps); + llist_for_each_entry(map, &slotmaps->mappings, list) { + if (client_slot_equals(&map->client, &conn->client.slot)) { + _update_client_for_slotmap(map, conn->srv, NULL); + break; + } + } + slotmaps_unlock(slotmaps); +#if 0 ClientSlot_t clslot; RsproPDU_t *pdu; @@ -241,10 +320,16 @@ static void clnt_st_connected_bankd_onenter(struct osmo_fsm_inst *fi, uint32_t p static void clnt_st_connected_client(struct osmo_fsm_inst *fi, uint32_t event, void *data) { struct rspro_client_conn *conn = fi->priv; - struct slotmaps *slotmaps = conn->srv->slotmaps; - const struct RsproPDU_t *rx = NULL; + BankSlot_t bslot; + RsproPDU_t *tx; switch (event) { + case CLNTC_E_CL_CFG_BANKD: /* Send [new] Bankd information to client */ + bank_slot2rspro(&bslot, &conn->client.bankd.slot); + tx = rspro_gen_ConfigClientBankReq(&bslot, conn->client.bankd.ip, + conn->client.bankd.port); + client_conn_send(conn, tx); + break; default: OSMO_ASSERT(0); } @@ -254,7 +339,7 @@ static void clnt_st_connected_bankd(struct osmo_fsm_inst *fi, uint32_t event, vo { struct rspro_client_conn *conn = fi->priv; struct slotmaps *slotmaps = conn->srv->slotmaps; - const struct RsproPDU_t *rx = NULL; + const RsproPDU_t *rx = NULL; struct slot_mapping *map, *map2; switch (event) { @@ -271,6 +356,7 @@ static void clnt_st_connected_bankd(struct osmo_fsm_inst *fi, uint32_t event, vo } _slotmap_state_change(map, SLMAP_S_ACTIVE, &conn->bank.maps_active); slotmaps_unlock(slotmaps); + _update_client_for_slotmap(map, conn->srv, conn); break; case CLNTC_E_REMOVE_MAP_RES: /* Bankd acknowledges mapping was removed */ rx = data; @@ -286,6 +372,7 @@ static void clnt_st_connected_bankd(struct osmo_fsm_inst *fi, uint32_t event, vo slotmaps_unlock(slotmaps); /* slotmap_del() will remove it from both global and bank list */ slotmap_del(map->maps, map); + /* FIXME: update client! */ break; case CLNTC_E_PUSH: /* check if any create or delete requests are pending */ slotmaps_wrlock(slotmaps); @@ -369,7 +456,7 @@ static const struct osmo_fsm_state server_client_fsm_states[] = { }, [CLNTC_ST_CONNECTED_CLIENT] = { .name = "CONNECTED_CLIENT", - .in_event_mask = 0, + .in_event_mask = S(CLNTC_E_CL_CFG_BANKD), .action = clnt_st_connected_client, .onenter = clnt_st_connected_client_onenter, }, diff --git a/src/server/rspro_server.h b/src/server/rspro_server.h index af84c18..6dd498e 100644 --- a/src/server/rspro_server.h +++ b/src/server/rspro_server.h @@ -49,6 +49,12 @@ struct rspro_client_conn { } bank; struct { struct client_slot slot; + /* bankd configuration for this client (if any) */ + struct { + struct bank_slot slot; + uint32_t ip; + uint16_t port; + } bankd; } client; }; |