+
+/**
+ * gras_trp_socket_new:
+ *
+ * Malloc a new socket, and initialize it with defaults
+ */
+void gras_trp_socket_new(int incoming,
+ gras_socket_t *dst) {
+
+ gras_socket_t sock=xbt_new0(s_gras_socket_t,1);
+
+ DEBUG1("Create a new socket (%p)", (void*)sock);
+
+ sock->plugin = NULL;
+
+ sock->incoming = incoming ? 1:0;
+ sock->outgoing = incoming ? 0:1;
+ sock->accepting = incoming ? 1:0;
+ sock->meas = 0;
+ sock->recv_ok = 1;
+
+ sock->sd = -1;
+ sock->port = -1;
+ sock->peer_port = -1;
+ sock->peer_name = NULL;
+ sock->peer_proc = NULL;
+
+ sock->data = NULL;
+ sock->bufdata = NULL;
+
+ *dst = sock;
+
+ xbt_dynar_push(((gras_trp_procdata_t)
+ gras_libdata_by_id(gras_trp_libdata_id))->sockets,dst);
+ XBT_OUT;
+}
+
+/**
+ * @brief Opens a server socket and makes it ready to be listened to.
+ * @param port: port on which you want to listen
+ * @param buf_size: size of the buffer (in byte) on the socket (for TCP sockets only). If 0, a sain default is used (32k, but may change)
+ * @param measurement: whether this socket is meant to convey measurement (if you don't know, use 0 to exchange regular messages)
+ *
+ * In real life, you'll get a TCP socket.
+ */
+gras_socket_t
+gras_socket_server_ext(unsigned short port,
+
+ unsigned long int buf_size,
+ int measurement) {
+
+ xbt_ex_t e;
+ gras_trp_plugin_t trp;
+ gras_socket_t sock;
+
+ DEBUG2("Create a server socket from plugin %s on port %d",
+ gras_if_RL() ? "tcp" : "sg",
+ port);
+ trp = gras_trp_plugin_get_by_name(gras_if_SG() ? "sg":"tcp");
+
+ /* defaults settings */
+ gras_trp_socket_new(1,&sock);
+ sock->plugin= trp;
+ sock->port=port;
+ sock->buf_size = buf_size>0 ? buf_size : 32*1024;
+ sock->meas = measurement;
+
+ /* Call plugin socket creation function */
+ DEBUG1("Prepare socket with plugin (fct=%p)",trp->socket_server);
+ TRY {
+ trp->socket_server(trp, sock);
+ DEBUG3("in=%c out=%c accept=%c",
+ sock->incoming?'y':'n',
+ sock->outgoing?'y':'n',
+ sock->accepting?'y':'n');
+ } CATCH(e) {
+ int cursor;
+ gras_socket_t sock_iter;
+ xbt_dynar_t socks = ((gras_trp_procdata_t) gras_libdata_by_id(gras_trp_libdata_id))->sockets;
+ xbt_dynar_foreach(socks, cursor, sock_iter) {
+ if (sock_iter==sock)
+ xbt_dynar_cursor_rm(socks,&cursor);
+ }
+ free(sock);
+ RETHROW;
+ }
+
+ if (!measurement)
+ ((gras_trp_procdata_t) gras_libdata_by_id(gras_trp_libdata_id))->myport = port;
+ return sock;
+}
+/**
+ * @brief Opens a server socket on any port in the given range
+ *
+ * @param minport: first port we will try
+ * @param maxport: last port we will try
+ * @param buf_size: size of the buffer (in byte) on the socket (for TCP sockets only). If 0, a sain default is used (32k, but may change)
+ * @param measurement: whether this socket is meant to convey measurement (if you don't know, use 0 to exchange regular messages)
+ *
+ * If none of the provided ports works, raises the exception got when trying the last possibility
+ */
+gras_socket_t
+gras_socket_server_range(unsigned short minport, unsigned short maxport,
+ unsigned long int buf_size, int measurement) {
+
+ int port;
+ gras_socket_t res=NULL;
+ xbt_ex_t e;
+
+ for (port=minport; port<maxport;port ++) {
+ TRY {
+ res=gras_socket_server_ext(port,buf_size,measurement);
+ } CATCH(e) {
+ if (port==maxport)
+ RETHROW;
+ xbt_ex_free(e);
+ }
+ return res;
+ }
+ THROW_IMPOSSIBLE;
+}
+
+/**
+ * @brief Opens a client socket to a remote host.
+ * @param host: who you want to connect to
+ * @param port: where you want to connect to on this host
+ * @param buf_size: size of the buffer (in bytes) on the socket (for TCP sockets only). If 0, a sain default is used (32k, but may change)
+ * @param measurement: whether this socket is meant to convey measurement (if you don't know, use 0 to exchange regular messages)
+ *
+ * In real life, you'll get a TCP socket.
+ */
+gras_socket_t
+gras_socket_client_ext(const char *host,
+ unsigned short port,
+
+ unsigned long int buf_size,
+ int measurement) {
+
+ xbt_ex_t e;
+ gras_trp_plugin_t trp;
+ gras_socket_t sock;
+
+ trp = gras_trp_plugin_get_by_name(gras_if_SG() ? "sg":"tcp");
+
+ DEBUG1("Create a client socket from plugin %s",gras_if_RL() ? "tcp" : "sg");
+ /* defaults settings */
+ gras_trp_socket_new(0,&sock);
+ sock->plugin= trp;
+ sock->peer_port = port;
+ sock->peer_name = (char*)strdup(host?host:"localhost");
+ sock->buf_size = buf_size>0 ? buf_size: 32*1024;
+ sock->meas = measurement;
+
+ /* plugin-specific */
+ TRY {
+ (*trp->socket_client)(trp, sock);
+ DEBUG3("in=%c out=%c accept=%c",
+ sock->incoming?'y':'n',
+ sock->outgoing?'y':'n',
+ sock->accepting?'y':'n');
+ } CATCH(e) {
+ free(sock);
+ RETHROW;
+ }
+
+ return sock;
+}
+
+/**
+ * gras_socket_server:
+ *
+ * Opens a server socket and make it ready to be listened to.
+ * In real life, you'll get a TCP socket.
+ */
+gras_socket_t
+gras_socket_server(unsigned short port) {
+ return gras_socket_server_ext(port,32*1024,0);
+}
+
+/** @brief Opens a client socket to a remote host */
+gras_socket_t
+gras_socket_client(const char *host,
+ unsigned short port) {
+ return gras_socket_client_ext(host,port,0,0);
+}
+
+/** @brief Opens a client socket to a remote host specified as '<host>:<port>' */
+gras_socket_t
+gras_socket_client_from_string(const char *host) {
+ xbt_host_t h = xbt_host_from_string(host);
+ gras_socket_t res = gras_socket_client_ext(h->name,h->port,0,0);
+ xbt_host_free(h);
+ return res;
+}
+
+/** \brief Close socket */
+void gras_socket_close(gras_socket_t sock) {
+ xbt_dynar_t sockets = ((gras_trp_procdata_t) gras_libdata_by_id(gras_trp_libdata_id))->sockets;
+ gras_socket_t sock_iter;