--- /dev/null
+/*\r
+ * Copyright (c) 2010 Intel Corporation. All rights reserved.\r
+ *\r
+ * This software is available to you under a choice of one of two\r
+ * licenses. You may choose to be licensed under the terms of the GNU\r
+ * General Public License (GPL) Version 2, available from the file\r
+ * COPYING in the main directory of this source tree, or the\r
+ * OpenIB.org BSD license below:\r
+ *\r
+ * Redistribution and use in source and binary forms, with or\r
+ * without modification, are permitted provided that the following\r
+ * conditions are met:\r
+ *\r
+ * - Redistributions of source code must retain the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer.\r
+ *\r
+ * - Redistributions in binary form must reproduce the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer in the documentation and/or other materials\r
+ * provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ */\r
+\r
+#if HAVE_CONFIG_H\r
+# include <config.h>\r
+#endif /* HAVE_CONFIG_H */\r
+\r
+#include <windows.h>\r
+#include <winsock2.h>\r
+\r
+#include "cma.h"\r
+#include <rdma/rdma_cma.h>\r
+#include <rdma/rdma_verbs.h>\r
+\r
+static void ucma_convert_to_ai(struct addrinfo *ai, struct rdma_addrinfo *rai)\r
+{\r
+ memset(ai, 0, sizeof *ai);\r
+ ai->ai_flags = rai->ai_flags;\r
+ ai->ai_family = rai->ai_family;\r
+\r
+ switch (rai->ai_qp_type) {\r
+ case IBV_QPT_RC:\r
+ ai->ai_socktype = SOCK_STREAM;\r
+ break;\r
+ case IBV_QPT_UD:\r
+ ai->ai_socktype = SOCK_DGRAM;\r
+ break;\r
+ }\r
+\r
+ switch (rai->ai_port_space) {\r
+ case RDMA_PS_TCP:\r
+ ai->ai_protocol = IPPROTO_TCP;\r
+ break;\r
+ case RDMA_PS_IPOIB:\r
+ case RDMA_PS_UDP:\r
+ ai->ai_protocol = IPPROTO_UDP;\r
+ break;\r
+ }\r
+\r
+ if (rai->ai_flags & RAI_PASSIVE) {\r
+ ai->ai_addrlen = rai->ai_src_len;\r
+ ai->ai_addr = rai->ai_src_addr;\r
+ } else {\r
+ ai->ai_addrlen = rai->ai_dst_len;\r
+ ai->ai_addr = rai->ai_dst_addr;\r
+ }\r
+ ai->ai_canonname = rai->ai_dst_canonname;\r
+ ai->ai_next = NULL;\r
+}\r
+\r
+static int ucma_convert_to_rai(struct rdma_addrinfo *rai, struct addrinfo *ai)\r
+{\r
+ struct sockaddr *addr;\r
+ char *canonname;\r
+\r
+ memset(rai, 0, sizeof *rai);\r
+ rai->ai_flags = ai->ai_flags;\r
+ rai->ai_family = ai->ai_family;\r
+\r
+ switch (ai->ai_socktype) {\r
+ case SOCK_STREAM:\r
+ rai->ai_qp_type = IBV_QPT_RC;\r
+ break;\r
+ case SOCK_DGRAM:\r
+ rai->ai_qp_type = IBV_QPT_UD;\r
+ break;\r
+ }\r
+\r
+ switch (ai->ai_protocol) {\r
+ case IPPROTO_TCP:\r
+ rai->ai_port_space = RDMA_PS_TCP;\r
+ break;\r
+ case IPPROTO_UDP:\r
+ rai->ai_port_space = RDMA_PS_UDP;\r
+ break;\r
+ }\r
+\r
+ addr = (struct sockaddr *) malloc(ai->ai_addrlen);\r
+ if (!addr)\r
+ return rdma_seterrno(ENOMEM);\r
+\r
+ canonname = (char *) (ai->ai_canonname ? malloc(strlen(ai->ai_canonname) + 1) : NULL);\r
+ if (canonname)\r
+ strcpy(canonname, ai->ai_canonname);\r
+\r
+ memcpy(addr, ai->ai_addr, ai->ai_addrlen);\r
+ if (ai->ai_flags & RAI_PASSIVE) {\r
+ rai->ai_src_addr = addr;\r
+ rai->ai_src_len = ai->ai_addrlen;\r
+ rai->ai_src_canonname = canonname;\r
+ } else {\r
+ rai->ai_dst_addr = addr;\r
+ rai->ai_dst_len = ai->ai_addrlen;\r
+ rai->ai_dst_canonname = canonname;\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+int rdma_getaddrinfo(char *node, char *service,\r
+ struct rdma_addrinfo *hints,\r
+ struct rdma_addrinfo **res)\r
+{\r
+ struct rdma_addrinfo *rai;\r
+ struct addrinfo ai_hints;\r
+ struct addrinfo *ai;\r
+ int ret;\r
+\r
+ if (hints)\r
+ ucma_convert_to_ai(&ai_hints, hints);\r
+\r
+ ret = getaddrinfo(node, service, &ai_hints, &ai);\r
+ if (ret)\r
+ return ret;\r
+\r
+ rai = (struct rdma_addrinfo *) malloc(sizeof(*rai));\r
+ if (!rai) {\r
+ ret = rdma_seterrno(ENOMEM);\r
+ goto err1;\r
+ }\r
+\r
+ ret = ucma_convert_to_rai(rai, ai);\r
+ if (ret)\r
+ goto err2;\r
+\r
+ if (!rai->ai_src_len && hints && hints->ai_src_len) {\r
+ rai->ai_src_addr = (struct sockaddr *) calloc(1, hints->ai_src_len);\r
+ if (!rai->ai_src_addr) {\r
+ ret = rdma_seterrno(ENOMEM);\r
+ goto err2;\r
+ }\r
+ memcpy(rai->ai_src_addr, hints->ai_src_addr,\r
+ hints->ai_src_len);\r
+ rai->ai_src_len = hints->ai_src_len;\r
+ }\r
+\r
+ // requires ib acm support --\r
+ //if (!(rai->ai_flags & RAI_PASSIVE))\r
+ // ucma_ib_resolve(rai);\r
+\r
+ freeaddrinfo(ai);\r
+ *res = rai;\r
+ return 0;\r
+\r
+err2:\r
+ rdma_freeaddrinfo(rai);\r
+err1:\r
+ freeaddrinfo(ai);\r
+ return ret;\r
+}\r
+\r
+void rdma_freeaddrinfo(struct rdma_addrinfo *res)\r
+{\r
+ struct rdma_addrinfo *rai;\r
+\r
+ while (res) {\r
+ rai = res;\r
+ res = res->ai_next;\r
+\r
+ if (rai->ai_connect)\r
+ free(rai->ai_connect);\r
+\r
+ if (rai->ai_route)\r
+ free(rai->ai_route);\r
+\r
+ if (rai->ai_src_canonname)\r
+ free(rai->ai_src_canonname);\r
+\r
+ if (rai->ai_dst_canonname)\r
+ free(rai->ai_dst_canonname);\r
+\r
+ if (rai->ai_src_addr)\r
+ free(rai->ai_src_addr);\r
+\r
+ if (rai->ai_dst_addr)\r
+ free(rai->ai_dst_addr);\r
+\r
+ free(rai);\r
+ }\r
+}\r