static int pscom_extoll_accept(pscom_con_t *con, int con_fd) { int arch = PSCOM_ARCH_EXTOLL; psex_con_info_t *ci = psex_con_create(); psex_info_msg_t msg; if (!ci) goto err_no_ci; if (psex_init()) goto out_noextoll; if (psex_con_init(ci, NULL, con)) goto dont_use; /* Initialize connection */ /* step 1: Yes, we talk extoll. */ pscom_writeall(con_fd, &arch, sizeof(arch)); /* step 2: Send Connection id's */ psex_con_get_info_msg(ci, &msg); pscom_writeall(con_fd, &msg, sizeof(msg)); /* step 3 : recv connection id's */ if ((pscom_readall(con_fd, &msg, sizeof(msg)) != sizeof(msg))) goto err_remote; /* Connect */ if (psex_con_connect(ci, &msg)) { /* ToDo: bad! How to inform the peer about the error? */ DPRINT(0, "Extoll psex_con_connect() failed!"); goto err_local; } pscom_extoll_con_init(con, con_fd, ci); return 1; /* --- */ err_local: err_remote: if (ci) psex_con_cleanup(ci); if (ci) psex_con_free(ci); return 0; /* --- */ dont_use: out_noextoll: psex_con_free(ci); err_no_ci: arch = PSCOM_ARCH_ERROR; pscom_writeall(con_fd, &arch, sizeof(arch)); return 0; /* Dont use extoll */ /* --- */ }
static void pscom_extoll_handshake(pscom_con_t *con, int type, void *data, unsigned size) { switch (type) { case PSCOM_INFO_ARCH_REQ: { psex_info_msg_t msg; psex_con_info_t *ci = psex_con_create(); con->arch.extoll.ci = ci; con->arch.extoll.reading = 0; if (psex_con_init(ci, NULL, con)) goto error_con_init; /* send my connection id's */ psex_con_get_info_msg(ci, &msg); pscom_precon_send(con->precon, PSCOM_INFO_EXTOLL_ID, &msg, sizeof(msg)); break; /* Next is PSCOM_INFO_EXTOLL_ID or PSCOM_INFO_ARCH_NEXT */ } case PSCOM_INFO_EXTOLL_ID: { psex_info_msg_t *msg = data; assert(sizeof(*msg) == size); if (psex_con_connect(con->arch.extoll.ci, msg)) goto error_con_connect; pscom_precon_send(con->precon, PSCOM_INFO_ARCH_OK, NULL, 0); break; /* Next is EOF or ARCH_NEXT */ } case PSCOM_INFO_ARCH_NEXT: /* Something failed. Cleanup. */ pscom_extoll_con_cleanup(con); break; /* Done. Extoll failed */ case PSCOM_INFO_EOF: pscom_extoll_init_con(con); break; /* Done. Use Extoll */ } return; /* --- */ error_con_connect: error_con_init: pscom_extoll_con_cleanup(con); pscom_precon_send_PSCOM_INFO_ARCH_NEXT(con->precon); }