static int udp_create_socket(int port, char *address) { struct sockaddr_in addr; int fd; UDP_DEBUG("Creating new listen socket on address "IPV4_ADDR" and port %d\n", IPV4_ADDR_FORMAT(inet_addr(address)), port); /* Create UDP socket */ if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { /* Socket creation has failed... */ UDP_ERROR("Socket creation failed (%s)\n", strerror(errno)); return fd; } memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = inet_addr(address); if (bind(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) { /* Bind failed */ UDP_ERROR("Socket bind failed (%s)\n", strerror(errno)); close(fd); return -1; } udp_fd = fd; if (pthread_create(&udp_recv_thread, NULL, &udp_receiver_thread, &fd) < 0) { UDP_ERROR("Pthred_create failed (%s)\n", strerror(errno)); return -1; } return fd; }
static int LUA_C_udp_send(lua_State* ls) { SOCKET_ST* st = (SOCKET_ST*)luaL_checkudata(ls, 1, gk_udp_register); size_t len = 0; const char* buf = luaL_checklstring(ls, 2, &len); if(lua_type(ls, 3) == LUA_TNUMBER) { sockaddr_in addr; addr.sin_addr.s_addr = lua_tointeger(ls, 3); xmsg msg; msg << (int)addr.sin_addr.s_net << '.' << (int)addr.sin_addr.s_host << '.' << (int)addr.sin_addr.s_lh << '.' << (int)addr.sin_addr.s_impno; lua_pushstring(ls, msg.c_str()); lua_replace(ls, 3); } auto ip = luaL_optstring(ls, 3, "0.0.0.0"); auto port = luaL_optstring(ls, 4, "0"); try { auto addrto = AddrInfo(ip, port); if(addrto.sin_addr.S_un.S_addr == 0 && addrto.sin_port == 0) { addrto = st->addr; } while(len > 0) { int sendlen = ::sendto(st->sock, buf, len, 0, (const sockaddr *)&addrto, sizeof(addrto)); if(sendlen <= 0) { return UDP_ERROR(ls, st, xmsg() << "UDP发送失败:" << WSAGetLastError()); } len -= sendlen; buf += sendlen; } } catch(const runtime_error& err) { return UDP_ERROR(ls, st, xmsg() << "UDP发送错误:" << err.what()); } catch(...) { return UDP_ERROR(ls, st, "UDP发送异常"); } lua_settop(ls, 1); return 1; }
int udp_init(const mme_config_t *mme_config) { UDP_DEBUG("Initializing UDP task interface\n"); if (pthread_create(&udp_task_thread, NULL, &udp_intertask_interface, NULL) < 0) { UDP_ERROR("udp pthread_create (%s)\n", strerror(errno)); return -1; } UDP_DEBUG("Initializing UDP task interface: DONE\n"); return 0; }
static int LUA_C_udp_broadcast(lua_State* ls) { SOCKET_ST* st = (SOCKET_ST*)luaL_checkudata(ls, 1, gk_udp_register); const BOOL b = lua_toboolean(ls, 2); if(setsockopt(st->sock, SOL_SOCKET, SO_BROADCAST, (char*)&b, sizeof(b))) { return UDP_ERROR(ls, st, "设置UDP广播出错"); } lua_settop(ls, 1); return 1; }
static int LUA_C_udp_settimeout(lua_State* ls) { SOCKET_ST* st = (SOCKET_ST*)luaL_checkudata(ls, 1, gk_udp_register); const int timeout = luaL_checkinteger(ls, 2); if(setsockopt(st->sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout))) { return UDP_ERROR(ls, st, "设置UDP超时出错"); } lua_settop(ls, 1); return 1; }
void *udp_receiver_thread(void *args_p) { int *fd_p = (int*)args_p; int fd = *fd_p; while (1) { uint8_t buffer[1024]; int n; socklen_t from_len; struct sockaddr_in addr; from_len = (socklen_t)sizeof(struct sockaddr_in); if ((n = recvfrom(fd, buffer, sizeof(buffer), 0, (struct sockaddr *)&addr, &from_len)) < 0) { UDP_ERROR("Recvfrom failed %s\n", strerror(errno)); break; } else { MessageDef *message_p; Gtpv1uDataReq *gtpv1u_data_req_p; uint8_t *forwarded_buffer = NULL; forwarded_buffer = calloc(n, sizeof(uint8_t)); memcpy(forwarded_buffer, buffer, n); message_p = (MessageDef *)malloc(sizeof(MessageDef)); message_p->messageId = GTPV1U_DATA_REQ; message_p->originTaskId = TASK_UDP; message_p->destinationTaskId = TASK_GTPV1_U; gtpv1u_data_req_p = &message_p->msg.gtpv1uDataReq; gtpv1u_data_req_p->buffer = forwarded_buffer; gtpv1u_data_req_p->buffer_length = n; gtpv1u_data_req_p->port = htons(addr.sin_port); gtpv1u_data_req_p->peer_addr = addr.sin_addr.s_addr; UDP_DEBUG("Msg of length %d received from %s:%u\n", n, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); if (send_msg_to_task(TASK_GTPV1_U, message_p) < 0) { UDP_DEBUG("Failed to send message %d to task %d\n", GTPV1U_DATA_REQ, TASK_GTPV1_U); break; } } } close(fd); fd = -1; free(args_p); return NULL; }
static int LUA_C_udp_recv(lua_State* ls) { SOCKET_ST* st = (SOCKET_ST*)luaL_checkudata(ls, 1, gk_udp_register); char buf[0x800]; const int len = luaL_optinteger(ls, 2, sizeof(buf)); char* lp = buf; if(len > sizeof(buf)) { lp = new char[len]; } sockaddr_in addr; int addrlen = sizeof(addr); memset(&addr, 0, sizeof(addr)); int recvlen = ::recvfrom(st->sock, lp, len, 0, (sockaddr*)&addr, &addrlen); if(recvlen == 0) { if(lp != buf) delete[] lp; return UDP_ERROR(ls, st, "UDP接收失败,SOCKET已关闭"); } if(recvlen == SOCKET_ERROR) { const int codes = WSAGetLastError(); switch(codes) { case WSAETIMEDOUT: if(lp != buf) delete[] lp; lua_pushnil(ls); lua_pushstring(ls, "timeout"); return 2; case WSAEMSGSIZE: if(lp != buf) delete[] lp; lua_pushnil(ls); lua_pushstring(ls, "msgsize"); return 2; default: { if(lp != buf) delete[] lp; return UDP_ERROR(ls, st, xmsg() << "UDP接收失败:" << codes); } } } lua_pushlstring(ls, lp, recvlen); if(lp != buf) delete[] lp; xmsg msg; msg << (int)addr.sin_addr.s_net << '.' << (int)addr.sin_addr.s_host << '.' << (int)addr.sin_addr.s_lh << '.' << (int)addr.sin_addr.s_impno; lua_pushstring(ls, msg.c_str()); msg.clear(); msg << (int)htons(addr.sin_port); lua_pushstring(ls, msg.c_str()); lua_pushinteger(ls, htonl(addr.sin_addr.S_un.S_addr)); lua_pushinteger(ls, htons(addr.sin_port)); return 5; }