【问题标题】:C Memory leak with packetsender socketC 与 packetsender 套接字的内存泄漏
【发布时间】:2015-05-30 04:23:24
【问题描述】:

大家好,我正在尝试为使用 JNI 的 SIP 应用程序编写具有 IP 欺骗功能的数据包发送器共享库,当我尝试运行应用程序并调用本机方法时,一开始没有任何问题,但一段时间后我认为内存泄漏发生时没有任何痕迹并导致 JVM 崩溃,我的 C 代码(如下)受this 的影响很大,这是我用 JNI 调用的方法,谁能帮我找到泄漏?

int send_message(const char * sip_msg, const char * dest_ip, int dest_port, const char * spoofed_ip, unsigned int source_port){
unsigned int source_ip = 0;
srand(time(0));
if(source_port == 0){
    source_port = rand() % 65535;
}
//unsigned int source_port = 0;
struct ip *ip;
struct udphdr *udp;
unsigned char packet[65535];
int len;
unsigned int msg_len =strlen(sip_msg);

struct sockaddr_in serv_addr;

int sockfd;
if ((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
    printf("\n Error : Could not create socket \n");
    return 1;
}

const int on = 1;
if (setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) == -1) {
    perror("\n Error : Set Sock Opt \n");
    return 1;
}

serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(dest_port);
serv_addr.sin_addr.s_addr = inet_addr(dest_ip);

len = sizeof(struct ip) + sizeof(struct udphdr) + msg_len;

if (len > sizeof(packet)) {
    printf("Failed to send1!\n");
    return -2;
}

ip = (struct ip*) packet;
udp = (struct udphdr *) (packet + sizeof(struct ip));
memcpy(packet+sizeof(struct ip)+sizeof(struct udphdr),sip_msg,msg_len);


ip->ip_v = 4;
ip->ip_hl = sizeof(struct ip) / 4; // no options
ip->ip_tos = 0;
ip->ip_len = htons(len);
ip->ip_id = 23;
ip->ip_off = 0;
ip->ip_ttl = 69;
ip->ip_p = 17;
ip->ip_src.s_addr = inet_addr(spoofed_ip);
ip->ip_dst.s_addr = inet_addr(dest_ip);

ip->ip_sum = checksum((unsigned char *) ip, sizeof(struct ip));

/*if (source_port == 0) {
    source_port = 5060;
}*/

udp->source = htons(source_port);
udp->dest = serv_addr.sin_port;
udp->len = htons((unsigned short) sizeof(struct udphdr) + msg_len);
udp->check = 0;

if (sendto(sockfd, packet, len, 0, (struct sockaddr *) (&serv_addr),
        sizeof(struct sockaddr_in)) == -1) {
    return -2;
    printf("Failed to send!\n");
}

    close(sockfd);


return 0;}

【问题讨论】:

  • 你试过像jnetpcap.com这样的libpcap包装库吗?您可以使用该库执行此操作,而无需编写此低级代码。即不需要 C 代码。
  • @PeterLawrey 我以前听说过,但从未使用过 :) 你能给我发一些这个库的 UDP 示例吗?
  • 快速谷歌找到gist.github.com/alexcheng1982/7108987我没试过。

标签: java c sockets memory-leaks java-native-interface


【解决方案1】:

是的,我可以找到 a 泄漏,不一定是 泄漏。

考虑一下会发生什么,例如sendto 失败。套接字已用socket() 打开,但您没有关闭它。您确实需要close 套接字以获取所有可以采用的代码路径。顺便说一句,在这种情况下,使用 goto 可能是个好主意。

【讨论】:

  • 所以我猜你是说当 sendto 失败时,如果发生过多 sendto 失败,那么套接字会在超时时保持打开状态,然后套接字会保持打开状态这会导致内存泄漏我是对的吗?
  • 是的,这正是我要说的。并不是说我确定这是您的泄漏,但这仍然是您应该解决的问题。修复除了sendto失败之外的其他代码路径。
猜你喜欢
  • 1970-01-01
  • 2015-08-26
  • 1970-01-01
  • 2023-03-29
  • 2015-06-28
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多