/* ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- */ void server_handle_request(CFMachPortRef port, void *msg, CFIndex size, void *info) { mach_msg_return_t r; mach_msg_header_t * request = (mach_msg_header_t *)msg; mach_msg_header_t * reply; char reply_s[128] __attribute__ ((aligned (4))); // Wcast-align fix - force alignment if (process_notification(request) == FALSE) { if (_pppcontroller_subsystem.maxsize > sizeof(reply_s)) { syslog(LOG_ERR, "PPPController: %d > %ld", _pppcontroller_subsystem.maxsize, sizeof(reply_s)); reply = (mach_msg_header_t *) malloc(_pppcontroller_subsystem.maxsize); } else { reply = ALIGNED_CAST(mach_msg_header_t *)reply_s; } if (pppcontroller_server(request, reply) == FALSE) { syslog(LOG_INFO, "unknown message ID (%d) received", request->msgh_id); mach_msg_destroy(request); } else { int options; options = MACH_SEND_MSG; if (MACH_MSGH_BITS_REMOTE(reply->msgh_bits) == MACH_MSG_TYPE_MOVE_SEND) { options |= MACH_SEND_TIMEOUT; } r = mach_msg(reply, options, reply->msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (r != MACH_MSG_SUCCESS) { syslog(LOG_INFO, "PPPController: mach_msg(send): %s", mach_error_string(r)); mach_msg_destroy(reply); } } if (reply != ALIGNED_CAST(mach_msg_header_t *)reply_s) { free(reply); } } return; }
STATIC void server_handle_request(CFMachPortRef port, void * msg, CFIndex size, void * info) { mach_msg_return_t r; mach_msg_header_t * request = (mach_msg_header_t *)msg; mach_msg_header_t * reply; char reply_s[eapolcfg_auth_subsystem.maxsize]; if (process_notification(request) == FALSE) { reply = (mach_msg_header_t *)reply_s; if (eapolcfg_auth_server(request, reply) == FALSE) { syslog(LOG_NOTICE, "eapolcfg_auth: unknown message ID (%d)", request->msgh_id); mach_msg_destroy(request); } else { int options; S_handled_request = TRUE; options = MACH_SEND_MSG; if (MACH_MSGH_BITS_REMOTE(reply->msgh_bits) != MACH_MSG_TYPE_MOVE_SEND_ONCE) { options |= MACH_SEND_TIMEOUT; } r = mach_msg(reply, options, reply->msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (r != MACH_MSG_SUCCESS) { syslog(LOG_NOTICE, "eapolcfg_auth: mach_msg(send): %s", mach_error_string(r)); mach_msg_destroy(reply); } } } return; }
int main(int argc, char **argv) { int fd, n, addr_len, len, msg_flags, close_time, i; size_t buffer_size; fd_set rset; char buffer[1000]; struct sctp_event_subscribe evnts; struct sctp_sndrcvinfo sri; struct sockaddr_in local_addr, remote_addr; struct sctp_setprim set_prim; i = 0; if (argc < 4) { printf("Usage: client2 local_port remote_addr remote_port [autoclose]\n"); exit(-1); } if ((fd = ext_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP)) < 0) perror("socket"); bzero(&evnts, sizeof(evnts)); evnts.sctp_data_io_event = 1; evnts.sctp_association_event = 1; evnts.sctp_address_event = 1; evnts.sctp_send_failure_event = 1; evnts.sctp_peer_error_event = 1; evnts.sctp_shutdown_event = 1; evnts.sctp_partial_delivery_event = 1; evnts.sctp_adaption_layer_event = 1; if (ext_setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts)) < 0) perror("setsockopt"); if (argc > 4) { close_time = atoi(argv[4]); if (ext_setsockopt(fd, IPPROTO_SCTP, SCTP_AUTOCLOSE, &close_time, sizeof(close_time)) < 0) perror("setsockopt"); } bzero(&local_addr, sizeof(struct sockaddr_in)); local_addr.sin_family = AF_INET; #ifdef HAVE_SIN_LEN local_addr.sin_len = sizeof(struct sockaddr_in); #endif local_addr.sin_addr.s_addr = htonl(INADDR_ANY); local_addr.sin_port = htons(atoi(argv[1])); if (ext_bind(fd, (struct sockaddr *) &local_addr, sizeof(local_addr)) != 0) perror("bind"); remote_addr.sin_family = AF_INET; remote_addr.sin_port = htons(atoi(argv[3])); #ifdef HAVE_SIN_LEN remote_addr.sin_len = sizeof(struct sockaddr_in); #endif remote_addr.sin_addr.s_addr = inet_addr(argv[2]); FD_ZERO(&rset); while (1) { FD_SET(fd, &rset); FD_SET(0, &rset); n = ext_select(fd + 1, &rset, NULL, NULL, NULL); if (n == 0) { printf("Timer was runnig off.\n"); } if (FD_ISSET(0, &rset)) { printf("Reading from stdin.\n"); len = ext_read(0, (void *) buffer, sizeof(buffer)); if (len == 0) break; if (num_rem > 0) { i = (i + 1) % num_rem; set_prim.ssp_assoc_id = assoc_id; memcpy(&set_prim.ssp_addr, sar + i, sizeof(struct sockaddr_in)); memcpy(&remote_addr, sar + i, sizeof(struct sockaddr_in)); if (ext_setsockopt(fd, IPPROTO_SCTP, SCTP_PRIMARY_ADDR, (void *) &set_prim, sizeof(set_prim)) < 0) perror("setprim"); } if (ext_sendto(fd, (const void *)buffer, len, 0, (const struct sockaddr *)&remote_addr, sizeof(remote_addr)) != len) perror("sendto"); else printf("Message of length %d sent to %s:%u: %.*s", len, inet_ntoa(remote_addr.sin_addr), ntohs(remote_addr.sin_port), len, buffer); } if (FD_ISSET(fd, &rset)) { printf("Reading from network.\n"); addr_len = sizeof(struct sockaddr_in); buffer_size = sizeof(buffer); if ((len = sctp_recvmsg(fd, (void *) buffer, buffer_size , (struct sockaddr *)&remote_addr, &addr_len, &sri,&msg_flags)) < 0) perror("recvfrom"); else { if(msg_flags & MSG_NOTIFICATION) { process_notification(fd, buffer); continue; } else { printf("Message of length %d received from %s:%u: %.*s", len, inet_ntoa(remote_addr.sin_addr), ntohs(remote_addr.sin_port), len, buffer); } } } } sctp_freepaddrs(sar); if (ext_close(fd) < 0) perror("close"); sleep(2); return 0; }
void replication_run(void) { if (!session) { return; } jsonrpc_session_run(session); for (int i = 0; jsonrpc_session_is_connected(session) && i < 50; i++) { struct jsonrpc_msg *msg; unsigned int seqno; seqno = jsonrpc_session_get_seqno(session); if (seqno != session_seqno || state == RPL_S_INIT) { session_seqno = seqno; request_ids_clear(); struct jsonrpc_msg *request; request = jsonrpc_create_request("list_dbs", json_array_create_empty(), NULL); request_ids_add(request->id, NULL); jsonrpc_session_send(session, request); replication_dbs_destroy(); replication_dbs = replication_db_clone(&local_dbs); state = RPL_S_DB_REQUESTED; VLOG_DBG("Send list_dbs request"); } msg = jsonrpc_session_recv(session); if (!msg) { continue; } if (msg->type == JSONRPC_NOTIFY && state != RPL_S_ERR && !strcmp(msg->method, "update")) { if (msg->params->type == JSON_ARRAY && msg->params->u.array.n == 2 && msg->params->u.array.elems[0]->type == JSON_STRING) { char *db_name = msg->params->u.array.elems[0]->u.string; struct ovsdb *db = find_db(db_name); if (db) { struct ovsdb_error *error; error = process_notification(msg->params->u.array.elems[1], db); if (error) { ovsdb_error_assert(error); state = RPL_S_ERR; } } } } else if (msg->type == JSONRPC_REPLY) { struct ovsdb *db; if (!request_ids_lookup_and_free(msg->id, &db)) { VLOG_WARN("received unexpected reply"); goto next; } switch (state) { case RPL_S_DB_REQUESTED: if (msg->result->type != JSON_ARRAY) { struct ovsdb_error *error; error = ovsdb_error("list-dbs failed", "list_dbs response is not array"); ovsdb_error_assert(error); state = RPL_S_ERR; } else { size_t i; for (i = 0; i < msg->result->u.array.n; i++) { const struct json *name = msg->result->u.array.elems[i]; if (name->type == JSON_STRING) { /* Send one schema request for each remote DB. */ const char *db_name = json_string(name); struct ovsdb *db = find_db(db_name); if (db) { struct jsonrpc_msg *request = jsonrpc_create_request( "get_schema", json_array_create_1( json_string_create(db_name)), NULL); request_ids_add(request->id, db); jsonrpc_session_send(session, request); } } } VLOG_DBG("Send schema requests"); state = RPL_S_SCHEMA_REQUESTED; } break; case RPL_S_SCHEMA_REQUESTED: { struct ovsdb_schema *schema; struct ovsdb_error *error; error = ovsdb_schema_from_json(msg->result, &schema); if (error) { ovsdb_error_assert(error); state = RPL_S_ERR; } if (db != find_db(schema->name)) { /* Unexpected schema. */ VLOG_WARN("unexpected schema %s", schema->name); state = RPL_S_ERR; } else if (!ovsdb_schema_equal(schema, db->schema)) { /* Schmea version mismatch. */ VLOG_INFO("Schema version mismatch, %s not replicated", schema->name); shash_find_and_delete(replication_dbs, schema->name); } ovsdb_schema_destroy(schema); /* After receiving schemas, reset the local databases that * will be monitored and send out monitor requests for them. */ if (hmap_is_empty(&request_ids)) { struct shash_node *node, *next; SHASH_FOR_EACH_SAFE (node, next, replication_dbs) { db = node->data; struct ovsdb_error *error = reset_database(db); if (error) { const char *db_name = db->schema->name; shash_find_and_delete(replication_dbs, db_name); ovsdb_error_assert(error); VLOG_WARN("Failed to reset database, " "%s not replicated.", db_name); } } if (shash_is_empty(replication_dbs)) { VLOG_WARN("Nothing to replicate."); state = RPL_S_ERR; } else { SHASH_FOR_EACH (node, replication_dbs) { db = node->data; struct ovsdb *db = node->data; struct jsonrpc_msg *request = create_monitor_request(db); request_ids_add(request->id, db); jsonrpc_session_send(session, request); VLOG_DBG("Send monitor requests"); state = RPL_S_MONITOR_REQUESTED; } } } break; } case RPL_S_MONITOR_REQUESTED: { /* Reply to monitor requests. */ struct ovsdb_error *error; error = process_notification(msg->result, db); if (error) { ovsdb_error_assert(error); state = RPL_S_ERR; } else { /* Transition to replicating state after receiving * all replies of "monitor" requests. */ if (hmap_is_empty(&request_ids)) { VLOG_DBG("Listening to monitor updates"); state = RPL_S_REPLICATING; } } break; } case RPL_S_ERR: /* Ignore all messages */ break; case RPL_S_INIT: case RPL_S_REPLICATING: default: OVS_NOT_REACHED(); } }