From d0d88da8754bd5184be826dc4d271c5abeece0c5 Mon Sep 17 00:00:00 2001 From: David Brodski Date: Wed, 20 Apr 2011 04:51:01 +0000 Subject: More cleanup, some errors, message in timeout implemented --- src/transport/gnunet-transport-wlan-helper.c | 548 +---------------------- src/transport/plugin_transport_wlan.c | 261 +++++++---- src/transport/test_transport_api_wlan_peer1.conf | 4 +- src/transport/test_transport_api_wlan_peer2.conf | 4 +- 4 files changed, 193 insertions(+), 624 deletions(-) (limited to 'src/transport') diff --git a/src/transport/gnunet-transport-wlan-helper.c b/src/transport/gnunet-transport-wlan-helper.c index 2cb14b4c6..633b2776c 100644 --- a/src/transport/gnunet-transport-wlan-helper.c +++ b/src/transport/gnunet-transport-wlan-helper.c @@ -131,37 +131,14 @@ struct Hardware_Infos struct sendbuf *write_pout; int fd_in, arptype_in; int fd_out; - //int arptype_out; - //int fd_main; - //int fd_rtc; DRIVER_TYPE drivertype; /* inited to DT_UNKNOWN on allocation by wi_alloc */ - //FILE *f_cap_in; - - //struct pcap_file_header pfh_in; - - //int sysfs_inject; - //int channel; - //int freq; - //int rate; - //int tx_power; - //char *wlanctlng; /* XXX never set */ - //char *iwpriv; - //char *iwconfig; - //char *ifconfig; char *iface; - //char *main_if; unsigned char pl_mac[6]; -//int inject_wlanng; }; -//#include "radiotap.h" -// mac of this node -/*char mac[] = - { 0x13, 0x22, 0x33, 0x44, 0x55, 0x66 }; - */ /* wifi bitrate to use in 500kHz units */ /* @@ -171,87 +148,13 @@ struct Hardware_Infos 54 * 2, 48 * 2, 36 * 2, 24 * 2, 18 * 2, 12 * 2, 9 * 2, 11 * 2, 11, // 5.5 2 * 2, 1 * 2 }; - #define OFFSET_FLAGS 0x10 - #define OFFSET_RATE 0x11 - */ -// this is where we store a summary of the -// information from the radiotap header - -/* - typedef struct - { - int m_nChannel; - int m_nChannelFlags; - int m_nRate; - int m_nAntenna; - int m_nRadiotapFlags; - }__attribute__((packed)) PENUMBRA_RADIOTAP_DATA; - */ +*/ static void sigfunc_hw(int sig) { closeprog = 1; } -/* - void - Dump(u8 * pu8, int nLength) - { - char sz[256], szBuf[512], szChar[17], *buf, fFirst = 1; - unsigned char baaLast[2][16]; - uint n, nPos = 0, nStart = 0, nLine = 0, nSameCount = 0; - - buf = szBuf; - szChar[0] = '\0'; - - for (n = 0; n < nLength; n++) - { - baaLast[(nLine & 1) ^ 1][n & 0xf] = pu8[n]; - if ((pu8[n] < 32) || (pu8[n] >= 0x7f)) - szChar[n & 0xf] = '.'; - else - szChar[n & 0xf] = pu8[n]; - szChar[(n & 0xf) + 1] = '\0'; - nPos += sprintf(&sz[nPos], "%02X ", baaLast[(nLine & 1) ^ 1][n & 0xf]); - if ((n & 15) != 15) - continue; - if ((memcmp(baaLast[0], baaLast[1], 16) == 0) && (!fFirst)) - { - nSameCount++; - } - else - { - if (nSameCount) - buf += sprintf(buf, "(repeated %d times)\n", nSameCount); - buf += sprintf(buf, "%04x: %s %s\n", nStart, sz, szChar); - nSameCount = 0; - printf("%s", szBuf); - buf = szBuf; - } - nPos = 0; - nStart = n + 1; - nLine++; - fFirst = 0; - sz[0] = '\0'; - szChar[0] = '\0'; - } - if (nSameCount) - buf += sprintf(buf, "(repeated %d times)\n", nSameCount); - - buf += sprintf(buf, "%04x: %s", nStart, sz); - if (n & 0xf) - { - *buf++ = ' '; - while (n & 0xf) - { - buf += sprintf(buf, " "); - n++; - } - } - buf += sprintf(buf, "%s\n", szChar); - printf("%s", szBuf); - } - */ static void usage() { @@ -280,7 +183,7 @@ check_crc_buf_osdep(unsigned char *buf, int len) { unsigned long crc; - if (len < 0) + if (0 > len) return 0; crc = calc_crc_osdep(buf, len); @@ -289,88 +192,6 @@ check_crc_buf_osdep(unsigned char *buf, int len) >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]); } -/* Search a file recursively */ -/* - static char * - searchInside(const char * dir, const char * filename) - { - char * ret; - char * curfile; - struct stat sb; - int len, lentot; - DIR *dp; - struct dirent *ep; - - dp = opendir(dir); - if (dp == NULL) - { - return NULL; - } - - len = strlen(filename); - lentot = strlen(dir) + 256 + 2; - curfile = (char *) calloc(1, lentot); - - while ((ep = readdir(dp)) != NULL) - { - - memset(curfile, 0, lentot); - sprintf(curfile, "%s/%s", dir, ep->d_name); - - //Checking if it's the good file - if ((int) strlen(ep->d_name) == len && !strcmp(ep->d_name, filename)) - { - (void) closedir(dp); - return curfile; - } - lstat(curfile, &sb); - - //If it's a directory and not a link, try to go inside to search - if (S_ISDIR(sb.st_mode) && !S_ISLNK(sb.st_mode)) - { - //Check if the directory isn't "." or ".." - if (strcmp(".", ep->d_name) && strcmp("..", ep->d_name)) - { - //Recursive call - ret = searchInside(curfile, filename); - if (ret != NULL) - { - (void) closedir(dp); - free(curfile); - return ret; - } - } - } - } - (void) closedir(dp); - free(curfile); - return NULL; - } - */ -/* Search a wireless tool and return its path */ -/* - static char * - wiToolsPath(const char * tool) - { - char * path; - int i, nbelems; - static const char * paths[] = - { "/sbin", "/usr/sbin", "/usr/local/sbin", "/bin", "/usr/bin", - "/usr/local/bin", "/tmp" }; - - nbelems = sizeof(paths) / sizeof(char *); - - for (i = 0; i < nbelems; i++) - { - path = searchInside(paths[i], tool); - if (path != NULL) - return path; - } - - return NULL; - } - */ - static int linux_get_channel(struct Hardware_Infos *dev) { @@ -380,27 +201,19 @@ linux_get_channel(struct Hardware_Infos *dev) memset(&wrq, 0, sizeof(struct iwreq)); - /* - if (dev->main_if) - strncpy(wrq.ifr_name, dev->main_if, IFNAMSIZ ); - else*/ strncpy(wrq.ifr_name, dev->iface, IFNAMSIZ ); fd = dev->fd_in; - /* - if (dev->drivertype == DT_IPW2200) - fd = dev->fd_main; - */ - if (ioctl(fd, SIOCGIWFREQ, &wrq) < 0) + if (0 > ioctl(fd, SIOCGIWFREQ, &wrq)) return (-1); frequency = wrq.u.freq.m; - if (frequency > 100000000) + if (100000000 < frequency ) frequency /= 100000; - else if (frequency > 1000000) + else if (1000000 < frequency ) frequency /= 1000; - if (frequency > 1000) + if (1000 < frequency) chan = getChannelFromFrequency(frequency); else chan = frequency; @@ -423,7 +236,7 @@ linux_read(struct Hardware_Infos * dev, unsigned char *buf, int count, caplen = read(dev->fd_in, tmpbuf, count); if (0 > caplen) { - if (errno == EAGAIN) + if (EAGAIN == errno) return (0); perror("read failed"); @@ -432,11 +245,10 @@ linux_read(struct Hardware_Infos * dev, unsigned char *buf, int count, memset(buf, 0, sizeof(buf)); - /* XXX */ if (ri) memset(ri, 0, sizeof(*ri)); - if (dev->arptype_in == ARPHRD_IEEE80211_PRISM) + if (ARPHRD_IEEE80211_PRISM == dev->arptype_in ) { /* skip the prism header */ if (tmpbuf[7] == 0x40) @@ -476,7 +288,7 @@ linux_read(struct Hardware_Infos * dev, unsigned char *buf, int count, return (0); } - if (dev->arptype_in == ARPHRD_IEEE80211_FULL) + if (ARPHRD_IEEE80211_FULL == dev->arptype_in) { struct ieee80211_radiotap_iterator iterator; struct ieee80211_radiotap_header *rthdr; @@ -588,7 +400,7 @@ linux_read(struct Hardware_Infos * dev, unsigned char *buf, int count, caplen -= n; //detect fcs at the end, even if the flag wasn't set and remove it - if (fcs_removed == 0 && check_crc_buf_osdep(tmpbuf + n, caplen - 4) == 1) + if (0 == fcs_removed && 1== check_crc_buf_osdep(tmpbuf + n, caplen - 4)) { caplen -= 4; } @@ -615,7 +427,7 @@ linux_write(struct Hardware_Infos * dev, unsigned char *buf, unsigned int count) //usedrtap = 0; ret = write(dev->fd_out, buf, count); - if (ret < 0) + if (0 > ret) { if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || errno == ENOMEM) @@ -632,7 +444,7 @@ linux_write(struct Hardware_Infos * dev, unsigned char *buf, unsigned int count) /*if (usedrtap) ret -= letoh16(*p_rtlen); - if (ret < 0) + if (0 > ret) { if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || errno == ENOMEM) @@ -662,7 +474,7 @@ openraw(struct Hardware_Infos * dev, char * iface, int fd, int * arptype, memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1); - if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) + if (0 > ioctl(fd, SIOCGIFINDEX, &ifr)) { printf("Interface %s: \n", iface); perror("ioctl(SIOCGIFINDEX) failed"); @@ -677,7 +489,7 @@ openraw(struct Hardware_Infos * dev, char * iface, int fd, int * arptype, /* lookup the hardware type */ - if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) + if (0 > ioctl(fd, SIOCGIFHWADDR, &ifr)) { printf("Interface %s: \n", iface); perror("ioctl(SIOCGIFHWADDR) failed"); @@ -688,7 +500,7 @@ openraw(struct Hardware_Infos * dev, char * iface, int fd, int * arptype, memset(&wrq, 0, sizeof(struct iwreq)); strncpy(wrq.ifr_name, iface, IFNAMSIZ); - if (ioctl(fd, SIOCGIWMODE, &wrq) < 0) + if (0 > ioctl(fd, SIOCGIWMODE, &wrq)) { /* most probably not supported (ie for rtap ipw interface) * * so just assume its correctly set... */ @@ -717,7 +529,7 @@ openraw(struct Hardware_Infos * dev, char * iface, int fd, int * arptype, } /* bind the raw socket to the interface */ - if (bind(fd, (struct sockaddr *) &sll, sizeof(sll)) < 0) + if (0 > bind(fd, (struct sockaddr *) &sll, sizeof(sll))) { printf("Interface %s: \n", iface); perror("bind(ETH_P_ALL) failed"); @@ -726,7 +538,7 @@ openraw(struct Hardware_Infos * dev, char * iface, int fd, int * arptype, /* lookup the hardware type */ - if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) + if (0 > ioctl(fd, SIOCGIFHWADDR, &ifr)) { printf("Interface %s: \n", iface); perror("ioctl(SIOCGIFHWADDR) failed"); @@ -741,7 +553,7 @@ openraw(struct Hardware_Infos * dev, char * iface, int fd, int * arptype, != ARPHRD_IEEE80211_PRISM && ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL) { - if (ifr.ifr_hwaddr.sa_family == 1) + if (1 == ifr.ifr_hwaddr.sa_family) fprintf(stderr, "\nARP linktype is set to 1 (Ethernet) "); else fprintf(stderr, "\nUnsupported hardware link type %4d ", @@ -773,46 +585,8 @@ openraw(struct Hardware_Infos * dev, char * iface, int fd, int * arptype, int wlaninit(struct Hardware_Infos * dev, char *iface) { - - //char *iwpriv; char strbuf[512]; - //dev->inject_wlanng = 1; - //dev->rate = 2; /* default to 1Mbps if nothing is set */ - /* open raw socks */ - /* - dev->fd_in = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); - if (0 > dev->fd_in) - { - perror("socket(PF_PACKET) failed at fd_in"); - if (getuid() != 0) - fprintf(stderr, "This program requires root privileges.\n"); - return (1); - } - */ - /* - dev->fd_main = socket(PF_PACKET, SOCK_RAW, htons( ETH_P_ALL ) ); - if (0 > dev->fd_main) - { - perror("socket(PF_PACKET) failed at fd_main"); - if (getuid() != 0) - fprintf(stderr, "This program requires root privileges.\n"); - return (1); - } - */ - /* Check iwpriv existence */ - /* - iwpriv = wiToolsPath("iwpriv"); - dev->iwpriv = iwpriv; - dev->iwconfig = wiToolsPath("iwconfig"); - dev->ifconfig = wiToolsPath("ifconfig"); - - if (!iwpriv) - { - fprintf(stderr, "Can't find wireless tools, exiting.\n"); - goto close_in; - } - */ dev->fd_out = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (0 > dev->fd_out) { @@ -836,7 +610,7 @@ wlaninit(struct Hardware_Infos * dev, char *iface) snprintf(strbuf, sizeof(strbuf) - 1, "ls /sys/class/net/%s/phy80211/subsystem >/dev/null 2>/dev/null", iface); - if (system(strbuf) == 0) + if (0 == system(strbuf)) dev->drivertype = DT_MAC80211_RT; else @@ -860,7 +634,6 @@ wlaninit(struct Hardware_Infos * dev, char *iface) dev->iface = GNUNET_malloc(sizeof(char) *6); strncpy(dev->iface, iface, sizeof(char) * 6); - //dev->arptype_out = dev->arptype_in; return 0; close_out: close(dev->fd_out); @@ -938,7 +711,7 @@ stdin_send_hw(void *cls, void *client, const struct GNUNET_MessageHeader *hdr) sendsize = ntohs(hdr->size) - sizeof(struct Radiotap_Send) - sizeof(struct GNUNET_MessageHeader); - if ((sendsize) > MAXLINE * 2) + if (MAXLINE * 2 < sendsize) { fprintf(stderr, "Function stdin_send: Packet too big for buffer\n"); exit(1); @@ -950,8 +723,8 @@ stdin_send_hw(void *cls, void *client, const struct GNUNET_MessageHeader *hdr) exit(1); } - if (sendsize < sizeof(struct ieee80211_frame) - + sizeof(struct GNUNET_MessageHeader)) + if ( sizeof(struct ieee80211_frame) + + sizeof(struct GNUNET_MessageHeader) > sendsize) { fprintf(stderr, "Function stdin_send: packet too small\n"); exit(1); @@ -1034,7 +807,7 @@ maketest(unsigned char * buf, struct Hardware_Infos * dev) 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, // mac3 - in this case bssid 0x10, 0x86, //Sequence Control }; - if (first == 0) + if (0 == first) { memcpy(&u8aIeeeHeader, u8aIeeeHeader_def, sizeof(struct ieee80211_frame)); memcpy(u8aIeeeHeader.i_addr2, dev->pl_mac, 6); @@ -1062,7 +835,6 @@ hardwaremode(int argc, char *argv[]) uid_t uid; struct Hardware_Infos dev; - //struct ifreq ifreq; struct Radiotap_rx * rxinfo; uint8_t * mac = dev.pl_mac; int fdpin, fdpout; @@ -1084,12 +856,6 @@ hardwaremode(int argc, char *argv[]) /* not critical, continue anyway */ //} - /*printf("Device %s -> Ethernet %02x:%02x:%02x:%02x:%02x:%02x\n", - ifreq.ifr_name, (int) mac[0], (int) mac[1], (int) mac[2], (int) mac[3], - (int) mac[4], (int) mac[5]);*/ - - //return 0; - unsigned char * datastart; char readbuf[MAXLINE]; int readsize = 0; @@ -1293,11 +1059,6 @@ hardwaremode(int argc, char *argv[]) } } - else - { - //eof - //closeprog = 1; - } } } @@ -1334,269 +1095,6 @@ main(int argc, char *argv[]) ret = hardwaremode(argc, argv); } -#if 0 - u8 u8aSendBuffer[500]; - char szErrbuf[PCAP_ERRBUF_SIZE]; - int nCaptureHeaderLength = 0, n80211HeaderLength = 0, nLinkEncap = 0; - int nOrdinal = 0, r, nDelay = 100000; - int nRateIndex = 0, retval, bytes; - pcap_t *ppcap = NULL; - struct bpf_program bpfprogram; - char * szProgram = "", fBrokenSocket = 0; - u16 u16HeaderLen; - char szHostname[PATH_MAX]; - - if (gethostname(szHostname, sizeof (szHostname) - 1)) - { - perror("unable to get hostname"); - } - szHostname[sizeof (szHostname) - 1] = '\0'; - - printf("Packetspammer (c)2007 Andy Green GPL2\n"); - - while (1) - { - int nOptionIndex; - static const struct option optiona[] = - { - { "delay", required_argument, NULL, 'd'}, - { "fcs", no_argument, &flagMarkWithFCS, 1}, - { "help", no_argument, &flagHelp, 1}, - { "verbose", no_argument, &flagVerbose, 1}, - { 0, 0, 0, 0} - }; - int c = getopt_long(argc, argv, "d:hf", - optiona, &nOptionIndex); - - if (c == -1) - break; - switch (c) - { - case 0: // long option - break; - - case 'h': // help - usage(); - - case 'd': // delay - nDelay = atoi(optarg); - break; - - case 'f': // mark as FCS attached - flagMarkWithFCS = 1; - break; - - case 'v': //Verbose / readable output to cout - flagVerbose = 1; - break; - - default: - printf("unknown switch %c\n", c); - usage(); - break; - } - } - - if (optind >= argc) - usage(); - - // open the interface in pcap - - szErrbuf[0] = '\0'; - ppcap = pcap_open_live(argv[optind], 800, 1, 20, szErrbuf); - if (ppcap == NULL) - { - printf("Unable to open interface %s in pcap: %s\n", - argv[optind], szErrbuf); - return (1); - } - - //get mac from interface - - /*int sock, j, k; - char mac[32]; - - sock=socket(PF_INET, SOCK_STREAM, 0); - if (-1==sock) { - perror("can not open socket\n"); - return 1; - } - - if (-1==ioctl(sock, SIOCGIFHWADDR, &ifr)) { - perror("ioctl(SIOCGIFHWADDR) "); - return 1; - } - for (j=0, k=0; j<6; j++) { - k+=snprintf(mac+k, sizeof(mac)-k-1, j ? ":%02X" : "%02X", - (int)(unsigned int)(unsigned char)ifr.ifr_hwaddr.sa_data[j]); - } - mac[sizeof(mac)-1]='\0'; - */ - - //get header type - nLinkEncap = pcap_datalink(ppcap); - nCaptureHeaderLength = 0; - - switch (nLinkEncap) - { - - case DLT_PRISM_HEADER: - printf("DLT_PRISM_HEADER Encap\n"); - nCaptureHeaderLength = 0x40; - n80211HeaderLength = 0x20; // ieee80211 comes after this - szProgram = "radio[0x4a:4]==0x13223344"; - break; - - case DLT_IEEE802_11_RADIO: - printf("DLT_IEEE802_11_RADIO Encap\n"); - nCaptureHeaderLength = 0x40; - n80211HeaderLength = 0x18; // ieee80211 comes after this - szProgram = "ether[0x0a:4]==0x13223344"; - break; - - default: - printf("!!! unknown encapsulation on %s !\n", argv[1]); - return (1); - - } - - if (pcap_compile(ppcap, &bpfprogram, szProgram, 1, 0) == -1) - { - puts(szProgram); - puts(pcap_geterr(ppcap)); - return (1); - } - else - { - if (pcap_setfilter(ppcap, &bpfprogram) == -1) - { - puts(szProgram); - puts(pcap_geterr(ppcap)); - } - else - { - printf("RX Filter applied\n"); - } - pcap_freecode(&bpfprogram); - } - - pcap_setnonblock(ppcap, 1, szErrbuf); - - printf(" (delay between packets %dus)\n", nDelay); - - memset(u8aSendBuffer, 0, sizeof(u8aSendBuffer)); - - while (!fBrokenSocket) - { - u8 * pu8 = u8aSendBuffer; - struct pcap_pkthdr * ppcapPacketHeader = NULL; - struct ieee80211_radiotap_iterator rti; - PENUMBRA_RADIOTAP_DATA prd; - //init of the values - prd.m_nRate = 255; - prd.m_nChannel = 255; - prd.m_nAntenna = 255; - prd.m_nRadiotapFlags = 255; - u8 * pu8Payload = u8aSendBuffer; - int n, nRate; - - // receive - - retval = pcap_next_ex(ppcap, &ppcapPacketHeader, - (const u_char**) &pu8Payload); - - if (retval < 0) - { - fBrokenSocket = 1; - continue; - } - - if (retval != 1) - goto do_tx; - - u16HeaderLen = (pu8Payload[2] + (pu8Payload[3] << 8)); - - printf("rtap: "); - Dump(pu8Payload, u16HeaderLen); - - if (ppcapPacketHeader->len < (u16HeaderLen + n80211HeaderLength)) - continue; - - bytes = ppcapPacketHeader->len - (u16HeaderLen + n80211HeaderLength); - if (bytes < 0) - continue; - - if (ieee80211_radiotap_iterator_init(&rti, - (struct ieee80211_radiotap_header *) pu8Payload, bytes) < 0) - continue; - - while ((n = ieee80211_radiotap_iterator_next(&rti)) == 0) - { - - switch (rti.this_arg_index) - { - case IEEE80211_RADIOTAP_RATE: - prd.m_nRate = (*rti.this_arg); - break; - - case IEEE80211_RADIOTAP_CHANNEL: - prd.m_nChannel = le16_to_cpu(*((u16 *)rti.this_arg)); - prd.m_nChannelFlags = le16_to_cpu(*((u16 *)(rti.this_arg + 2))); - break; - - case IEEE80211_RADIOTAP_ANTENNA: - prd.m_nAntenna = (*rti.this_arg) + 1; - break; - - case IEEE80211_RADIOTAP_FLAGS: - prd.m_nRadiotapFlags = *rti.this_arg; - break; - - } - } - - pu8Payload += u16HeaderLen + n80211HeaderLength; - - if (prd.m_nRadiotapFlags & IEEE80211_RADIOTAP_F_FCS) - bytes -= 4; - - printf("RX: Rate: %2d.%dMbps, Freq: %d.%dGHz, " - "Ant: %d, Flags: 0x%X\n", prd.m_nRate / 2, 5 * (prd.m_nRate & 1), - prd.m_nChannel / 1000, prd.m_nChannel - ((prd.m_nChannel / 1000) - * 1000), prd.m_nAntenna, prd.m_nRadiotapFlags); - - Dump(pu8Payload, bytes); - - do_tx: - - // transmit - - memcpy(u8aSendBuffer, u8aRadiotapHeader, sizeof(u8aRadiotapHeader)); - if (flagMarkWithFCS) - pu8[OFFSET_FLAGS] |= IEEE80211_RADIOTAP_F_FCS; - nRate = pu8[OFFSET_RATE] = u8aRatesToUse[nRateIndex++]; - if (nRateIndex >= sizeof(u8aRatesToUse)) - nRateIndex = 0; - pu8 += sizeof(u8aRadiotapHeader); - - memcpy(pu8, u8aIeeeHeader, sizeof(u8aIeeeHeader)); - pu8 += sizeof(u8aIeeeHeader); - - pu8 += sprintf((char *) u8aSendBuffer, "Packetspammer %02d" - "broadcast packet" - "#%05d -- :-D --%s ----", nRate / 2, nOrdinal++, szHostname); - r = pcap_inject(ppcap, u8aSendBuffer, pu8 - u8aSendBuffer); - if (r != (pu8 - u8aSendBuffer)) - { - perror("Trouble injecting packet"); - return (1); - } - if (nDelay) - usleep(nDelay); - } - -#endif - return ret; maketest(NULL, NULL); } diff --git a/src/transport/plugin_transport_wlan.c b/src/transport/plugin_transport_wlan.c index f8178f101..f53e4b648 100644 --- a/src/transport/plugin_transport_wlan.c +++ b/src/transport/plugin_transport_wlan.c @@ -60,7 +60,7 @@ #define HALLO_BEACON_SCALING_FACTOR 900 -#define DEBUG_wlan GNUNET_YES +#define DEBUG_wlan GNUNET_NO #define DEBUG_wlan_retransmission GNUNET_NO #define MESSAGE_LENGHT_UNKNOWN -1 @@ -121,9 +121,13 @@ struct Plugin struct GNUNET_SERVER_MessageStreamTokenizer * suid_tokenizer; /** - * encapsulation of packets received + * encapsulation of packets received from the wlan helper */ struct GNUNET_SERVER_MessageStreamTokenizer * data_tokenizer; + /** + * encapsulation of packets received + */ + struct GNUNET_SERVER_MessageStreamTokenizer * fragment_tokenizer; /** * stdout pipe handle for the gnunet-wlan-helper process @@ -179,7 +183,7 @@ struct Plugin * Sessions currently pending for transmission * to this peer, if any. */ - struct Sessionqueue * pending_Sessions; + struct Sessionqueue * pending_Sessions_head; /** * Sessions currently pending for transmission @@ -244,7 +248,7 @@ struct Finish_send /** * Queue of sessions, for the general session queue and the pending session queue */ - +//TODO DOXIGEN struct Sessionqueue { struct Sessionqueue * next; @@ -255,6 +259,7 @@ struct Sessionqueue /** * Queue for the fragments received */ +//TODO DOXIGEN struct Receive_Fragment_Queue { struct Receive_Fragment_Queue * next; @@ -265,12 +270,15 @@ struct Receive_Fragment_Queue struct Radiotap_rx rxinfo; }; -struct Session_id_pair +//TODO DOXIGEN +struct Session_id_fragment_triple { struct Session * session; uint32_t message_id; + struct FragmentMessage * fm; }; +//TODO DOXIGEN struct Plugin_Session_pair { struct Plugin * plugin; @@ -367,13 +375,20 @@ struct PendingMessage /** * Queue for acks to send for fragments recived */ -//TODO comments struct AckSendQueue { + /** + * next ack in the ack send queue + */ struct AckSendQueue * next; + /** + * previous ack in the ack send queue + */ struct AckSendQueue * prev; - + /** + * pointer to the session this ack belongs to + */ struct Session * session; /** * ID of message, to distinguish between the messages, picked randomly. @@ -565,8 +580,6 @@ struct FragmentationAckHeader }; -static struct FragmentMessage * return_val; - static void do_transmit(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); @@ -726,8 +739,7 @@ get_session(struct Plugin *plugin, const struct MacAddress *addr) static void queue_session(struct Plugin *plugin, struct Session * session) { - struct Sessionqueue * queue = plugin->pending_Sessions; - struct Sessionqueue * lastitem = NULL; + struct Sessionqueue * queue = plugin->pending_Sessions_head; if (session->pending_message != NULL) { @@ -741,7 +753,6 @@ queue_session(struct Plugin *plugin, struct Session * session) return; } // try next - lastitem = queue; queue = queue->next; } @@ -751,16 +762,17 @@ queue_session(struct Plugin *plugin, struct Session * session) queue->content = session; //insert at the tail - GNUNET_CONTAINER_DLL_insert_tail(plugin->pending_Sessions, + GNUNET_CONTAINER_DLL_insert_tail(plugin->pending_Sessions_head, plugin->pending_Sessions_tail, queue); plugin->pendingsessions++; } } -//TODO doxigen /** * Function to schedule the write task, executed after a delay + * @param cls pointer to the plugin struct + * @param tc GNUNET_SCHEDULER_TaskContext pointer */ static void delay_fragment_task(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) @@ -780,10 +792,11 @@ delay_fragment_task(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } } -//TODO doxigen /** * Function to calculate the time of the next periodic "hello-beacon" + * @param plugin pointer to the plugin struct */ + static void set_next_beacon_time(struct Plugin * const plugin) { @@ -810,21 +823,11 @@ set_next_beacon_time(struct Plugin * const plugin) } } -//TODO doxigen -/* - static struct GNUNET_TIME_Relative - get_next_frag_timeout(struct FragmentMessage * fm) - { - return GNUNET_TIME_relative_min(GNUNET_TIME_absolute_get_remaining( - fm->next_ack), GNUNET_TIME_absolute_get_remaining(fm->timeout)); - } - */ - -//TODO doxigen /** * Function to get the timeout value for acks for this session + * @param fm pointer to the FragmentMessage to get the next timeout + * @return time until the next ack should be received, in GNUNET_TIME_Relative */ - static struct GNUNET_TIME_Relative get_ack_timeout(struct FragmentMessage * fm) { @@ -879,9 +882,20 @@ set_next_send(struct Plugin * const plugin) #endif - plugin->server_write_delay_task = GNUNET_SCHEDULER_add_delayed(next_send, - &delay_fragment_task, plugin); - + if (next_send.rel_value == GNUNET_TIME_UNIT_ZERO.rel_value) + { + if (plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK) + { + plugin->server_write_task = GNUNET_SCHEDULER_add_write_file( + GNUNET_TIME_UNIT_FOREVER_REL, plugin->server_stdin_handle, + &do_transmit, plugin); + } + } + else + { + plugin->server_write_delay_task = GNUNET_SCHEDULER_add_delayed(next_send, + &delay_fragment_task, plugin); + } } /** @@ -896,15 +910,19 @@ get_next_queue_session(struct Plugin * plugin) struct Sessionqueue * sessionqueue; struct Sessionqueue * sessionqueue_alt; struct PendingMessage * pm; - sessionqueue = plugin->pending_Sessions; + sessionqueue = plugin->pending_Sessions_head; while (sessionqueue != NULL) { session = sessionqueue->content; GNUNET_assert(session != NULL); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Found session %p from pending session queue\n", session + ); pm = session->pending_message; + #if DEBUG_wlan if (pm == NULL) { @@ -924,7 +942,7 @@ get_next_queue_session(struct Plugin * plugin) < FRAGMENT_QUEUE_MESSAGES_OUT_PER_SESSION) { plugin->pendingsessions--; - GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions, + GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head, plugin->pending_Sessions_tail, sessionqueue); GNUNET_free(sessionqueue); @@ -953,7 +971,7 @@ get_next_queue_session(struct Plugin * plugin) sessionqueue_alt = sessionqueue; sessionqueue = sessionqueue->next; plugin->pendingsessions--; - GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions, + GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head, plugin->pending_Sessions_tail, sessionqueue_alt); GNUNET_free(sessionqueue_alt); @@ -1082,9 +1100,9 @@ check_finished_fragment(struct Plugin * plugin, struct FragmentMessage * fm) #if DEBUG_wlan if (maxack != 63) - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Test bitfields %X and %X, maxack is %u, fm size %u\n", - fm->ack_bitfield, tmpfield, maxack, fm->message_size); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Test bitfields %X and %X, maxack is %u, fm size %u\n", + fm->ack_bitfield, tmpfield, maxack, fm->message_size); #endif if (fm->ack_bitfield == tmpfield) @@ -1143,6 +1161,7 @@ set_next_message_fragment_pos(struct Plugin * plugin, } +//TODO DOXIGEN static int getRadiotapHeader(struct Plugin * plugin, struct Session * session, struct Radiotap_Send * header) @@ -1223,6 +1242,7 @@ getcrc16(const char *msgbuf, size_t msgbuf_size) return 0; } +//TODO DOXIGEN static void send_hello_beacon(struct Plugin * plugin) { @@ -1278,6 +1298,7 @@ send_hello_beacon(struct Plugin * plugin) set_next_send(plugin); } +//TODO DOXIGEN static void send_ack(struct Plugin * plugin, struct AckSendQueue * ack) { @@ -1298,7 +1319,7 @@ send_ack(struct Plugin * plugin, struct AckSendQueue * ack) GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Sending ack for message_id %u with fragment field %u, size %u\n", ack->message_id, ack->fragments_field, size - - sizeof(struct Radiotap_Send)); + - sizeof(struct Radiotap_Send)); #endif msgheader = GNUNET_malloc(size); @@ -1330,6 +1351,7 @@ send_ack(struct Plugin * plugin, struct AckSendQueue * ack) set_next_send(plugin); } +//TODO DOXIGEN static void finish_sending(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { @@ -1459,7 +1481,7 @@ do_transmit(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_ERROR_TYPE_DEBUG, "Sending GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT with message_id %u with fragment number %i, size: %u, offset %u, time until timeout %u\n", fm->message_id_out, fm->message_pos, copysize - + sizeof(struct FragmentationHeader), copyoffset, + + sizeof(struct FragmentationHeader), copyoffset, GNUNET_TIME_absolute_get_remaining(fm->timeout)); #endif @@ -1473,21 +1495,11 @@ do_transmit(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) fm->message_pos); } GNUNET_assert(copyoffset < fm->message_size); - //FIXME remove later - GNUNET_assert(copystart < fm->msg + fm->message_size); fragheader.header.size = htons(copysize + sizeof(struct FragmentationHeader)); fragheader.header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT); - /* } - else - { - // there is no need to split - copystart = fm->msg; - copysize = fm->message_size; - }*/ - size += copysize; size += sizeof(struct Radiotap_Send) + sizeof(struct ieee80211_frame) + sizeof(struct GNUNET_MessageHeader); @@ -1503,18 +1515,11 @@ do_transmit(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) //could be faster if content is just send and not copyed before //fragmentheader is needed - //if (fm->message_size > WLAN_MTU) - // { fragheader.message_crc = htons(getcrc16(copystart, copysize)); memcpy(&ieeewlanheader[1], &fragheader, sizeof(struct FragmentationHeader)); fragheaderptr = (struct FragmentationHeader *) &ieeewlanheader[1]; memcpy(&fragheaderptr[1], copystart, copysize); - /* } - else - { - memcpy(&ieeewlanheader[1], copystart, copysize); - }*/ bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle, msgheader, size); @@ -1581,6 +1586,7 @@ do_transmit(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } return; } + GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "do_transmit did nothing, should not happen!\n"); } @@ -1786,13 +1792,14 @@ search_fragment_message_from_session_and_id(void *cls, struct GNUNET_CONTAINER_HeapNode *node, void *element, GNUNET_CONTAINER_HeapCostType cost) { - struct Session_id_pair * pair = (struct Session_id_pair *) cls; + struct Session_id_fragment_triple * triple = + (struct Session_id_fragment_triple *) cls; struct FragmentMessage * fm = (struct FragmentMessage*) element; - if ((fm->session == pair->session) - && (fm->message_id_out == pair->message_id)) + if ((fm->session == triple->session) && (fm->message_id_out + == triple->message_id)) { - return_val = fm; + triple->fm = fm; return GNUNET_NO; } return GNUNET_YES; @@ -1809,12 +1816,12 @@ static struct FragmentMessage * get_fragment_message_from_session_and_id(struct Plugin * plugin, struct Session * session, uint32_t message_id) { - struct Session_id_pair pair; - pair.session = session; - pair.message_id = message_id; + struct Session_id_fragment_triple triple; + triple.session = session; + triple.message_id = message_id; GNUNET_CONTAINER_heap_iterate(plugin->pending_Fragment_Messages, - &search_fragment_message_from_session_and_id, &pair); - return return_val; + &search_fragment_message_from_session_and_id, &triple); + return triple.fm; } /** @@ -1822,7 +1829,7 @@ get_fragment_message_from_session_and_id(struct Plugin * plugin, * @param plugin pointer to the plugin struct * @param session session this fragment belongs to */ -struct Receive_Message_Queue * +static struct Receive_Message_Queue * get_receive_message_from_session(struct Plugin * plugin, struct Session * session) { @@ -1868,28 +1875,59 @@ free_receive_message(struct Plugin* plugin, GNUNET_free(rx_message); } +/** + * function to get the receive message of a session + * @param plugin pointer to the plugin struct + * @param session session this fragment belongs to + */ +static void +check_receive_message_timeouts(struct Plugin * plugin, struct Session * session) +{ + struct Receive_Message_Queue * rec_message = plugin->receive_messages_head; + while (rec_message != NULL) + { + if (GNUNET_TIME_absolute_get_remaining(rec_message->timeout).rel_value + == 0) + { + free_receive_message(plugin, rec_message); + } + rec_message = rec_message->next; + } + +} + +//TODO DOXIGEN static void free_session(struct Plugin * plugin, struct Sessionqueue * queue) { - struct Sessionqueue * pendingsession = plugin->pending_Sessions; + struct Sessionqueue * pendingsession; + struct Sessionqueue * pendingsession_tmp; struct PendingMessage * pm; struct Receive_Message_Queue * receive_queue; struct Plugin_Session_pair pair; int check = 0; GNUNET_assert(queue != NULL); + GNUNET_assert(queue->content != NULL); //session found //is this session pending for send + pendingsession = plugin->pending_Sessions_head; while (pendingsession != NULL) { + pendingsession_tmp = pendingsession->next; if (pendingsession->content == queue->content) { plugin->pendingsessions--; - GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions, + GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head, plugin->pending_Sessions_tail, pendingsession); GNUNET_free(pendingsession); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Remove session %p from pending session queue\n", queue->content + ); + + if (check == 1) { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, @@ -1898,7 +1936,7 @@ free_session(struct Plugin * plugin, struct Sessionqueue * queue) check = 1; } - pendingsession = pendingsession->next; + pendingsession = pendingsession_tmp; } //is something of this session in the fragment queue? @@ -2099,10 +2137,11 @@ insert_fragment_in_queue(struct Receive_Message_Queue * rx_message, * @param hdr pointer to the data */ static void -wlan_data_message_handler(struct Plugin * plugin, - struct Session_light * session_light, - const struct GNUNET_MessageHeader * hdr) +wlan_data_message_handler(void *cls, void *client, + const struct GNUNET_MessageHeader *hdr) { + struct Plugin * plugin = (struct Plugin*) cls; + struct Session_light * session_light = (struct Session_light *) client; struct WlanHeader * wlanheader; struct Session * session; const char * tempmsg; @@ -2232,9 +2271,10 @@ check_rx_finished_msg(struct Plugin* plugin, struct Receive_Fragment_Queue * rx_frag = rx_message->frag_head; int packetsize = rx_message->rec_size; int sum; - int aktnum; + //TODO CLEANUP + //int aktnum; uint64_t bitfield = 0; - char * msg; + //char * msg; //check if first fragment is present if (packetsize == MESSAGE_LENGHT_UNKNOWN) @@ -2279,31 +2319,50 @@ check_rx_finished_msg(struct Plugin* plugin, "check_rec_finished_msg: A message for %p is complete\n", session); #endif - //TODO use mst + //TODO cleanup + //copy fragments together - msg = GNUNET_malloc(packetsize); + //msg = GNUNET_malloc(packetsize); rx_frag = rx_message->frag_head; - aktnum = 0; + //aktnum = 0; + /*while (rx_frag != NULL) + { + //TODO SAVE SOME COPY OPS AND CHECK CRC WITHOUT COPY + memcpy(msg + aktnum, rx_frag->msg, rx_frag->size); + aktnum += rx_frag->size; + rx_frag = rx_frag->next; + }*/ + while (rx_frag != NULL) { - //TODO SAVE SOME COPY OPS AND CHECK CRC WITHOUT COPY - memcpy(msg + aktnum, rx_frag->msg, rx_frag->size); - aktnum += rx_frag->size; + if (rx_frag->next != NULL) + { + GNUNET_SERVER_mst_receive(plugin->fragment_tokenizer, + session_light, rx_frag->msg, rx_frag->size, GNUNET_NO, + GNUNET_NO); + } + else + { + //if it is the last fragment just kill all leftover + GNUNET_SERVER_mst_receive(plugin->fragment_tokenizer, + session_light, rx_frag->msg, rx_frag->size, GNUNET_YES, + GNUNET_NO); + } rx_frag = rx_frag->next; } - free_receive_message(plugin, rx_message); //call wlan_process_helper to process the message - wlan_data_message_handler(plugin, session_light, - (struct GNUNET_MessageHeader*) msg); + //wlan_data_message_handler(plugin, session_light, + // (struct GNUNET_MessageHeader*) msg); //wlan_data_helper (plugin, session_light, (struct GNUNET_MessageHeader*) msg); - GNUNET_free(msg); + //GNUNET_free(msg); } } // } } +//TODO DOXIGEN static void process_data(void *cls, void *client, const struct GNUNET_MessageHeader *hdr) { @@ -2410,6 +2469,11 @@ insert_fragment_in_in_message_queue(struct Plugin * plugin, if (rx_message == NULL) { + if (session->fragment_messages_in_count < MESSAGES_IN_QUEUE_PER_SESSION) + { + check_receive_message_timeouts(plugin, session); + } + if (session->fragment_messages_in_count < MESSAGES_IN_QUEUE_PER_SESSION) { @@ -2418,8 +2482,6 @@ insert_fragment_in_in_message_queue(struct Plugin * plugin, rx_message->message_id_in = ntohl(fh->message_id); rx_message->rec_size = MESSAGE_LENGHT_UNKNOWN; rx_message->session = session; - rx_message->timeout = GNUNET_TIME_absolute_add( - GNUNET_TIME_absolute_get(), MESSAGE_IN_TIMEOUT); rx_message->received_fragments = 0; GNUNET_CONTAINER_DLL_insert(plugin->receive_messages_head, plugin->receive_messages_teil, rx_message); @@ -2447,6 +2509,11 @@ insert_fragment_in_in_message_queue(struct Plugin * plugin, } } + //reset timeout + rx_message->timeout = GNUNET_TIME_absolute_add( + GNUNET_TIME_absolute_get(), + MESSAGE_IN_TIMEOUT); + if (is_double_msg(rx_message, fh) != GNUNET_YES) { @@ -2576,8 +2643,12 @@ wlan_data_helper(void *cls, struct Session_light * session_light, GNUNET_ERROR_TYPE_INFO, "WLAN client not in session list, fragment num %u, message id %u\n", ntohs(fh->fragment_off_or_num), ntohl(fh->message_id)); - wlan_data_message_handler(plugin, session_light, - (struct GNUNET_MessageHeader *) tempmsg); + + GNUNET_SERVER_mst_receive(plugin->fragment_tokenizer, session_light, + tempmsg, ntohs(hdr->size) - sizeof(struct FragmentationHeader), + GNUNET_YES, GNUNET_NO); + //wlan_data_message_handler(plugin, session_light, + // (struct GNUNET_MessageHeader *) tempmsg); session = session_light->session; //test if a session was created if (session == NULL) @@ -2658,6 +2729,7 @@ wlan_data_helper(void *cls, struct Session_light * session_light, } +//TODO DOXIGEN const char * macprinter(const u_int8_t * mac) { @@ -2706,7 +2778,7 @@ wlan_process_helper(void *cls, void *client, GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Size of packet is too small; size: %u min size: %u\n", ntohs( hdr->size), sizeof(struct ieee80211_frame) - + sizeof(struct GNUNET_MessageHeader)); + + sizeof(struct GNUNET_MessageHeader)); #endif //GNUNET_break (0); /* FIXME: restart SUID process */ @@ -2812,12 +2884,6 @@ wlan_plugin_helper_read(void *cls, struct Plugin *plugin = cls; plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK; - /* - #if DEBUG_wlan - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Start reading from STDIN\n"); - #endif - */ if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) return; @@ -2935,6 +3001,9 @@ libgnunet_plugin_transport_wlan_done(void *cls) if (plugin->data_tokenizer != NULL) GNUNET_SERVER_mst_destroy(plugin->data_tokenizer); + if (plugin->fragment_tokenizer != NULL) + GNUNET_SERVER_mst_destroy(plugin->fragment_tokenizer); + fm = (struct FragmentMessage *) GNUNET_CONTAINER_heap_peek( plugin->pending_Fragment_Messages); @@ -2992,9 +3061,11 @@ libgnunet_plugin_transport_wlan_init(void *cls) plugin); plugin->data_tokenizer = GNUNET_SERVER_mst_create(&process_data, plugin); + plugin->fragment_tokenizer = GNUNET_SERVER_mst_create( + &wlan_data_message_handler, plugin); //plugin->sessions = GNUNET_malloc (sizeof (struct Sessionqueue)); - //plugin->pending_Sessions = GNUNET_malloc (sizeof (struct Sessionqueue)); + //plugin->pending_Sessions_head = GNUNET_malloc (sizeof (struct Sessionqueue)); api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); api->cls = plugin; diff --git a/src/transport/test_transport_api_wlan_peer1.conf b/src/transport/test_transport_api_wlan_peer1.conf index 683093ff7..b33abd243 100644 --- a/src/transport/test_transport_api_wlan_peer1.conf +++ b/src/transport/test_transport_api_wlan_peer1.conf @@ -9,7 +9,7 @@ AUTOSTART = NO [transport-wlan] INTERFACE = mon0 -TESTMODE = 0 +TESTMODE = 1 #PREFIX = gdbserver :2345 [hostlist] @@ -46,7 +46,7 @@ UNIXPATH = /tmp/gnunet-p1-service-transport.sock #PREFIX = xterm -T transport2 -e gdb --command=cmd --args #PREFIX = valgrind --leak-check=full --show-reachable=yes --main-stacksize=104857600 #PREFIX = valgrind --leak-check=full --show-reachable=yes -#PREFIX = valgrind --leak-check=full +PREFIX = valgrind --leak-check=full #PREFIX = valgrind --tool=massif #PREFIX = gdbserver :2345 diff --git a/src/transport/test_transport_api_wlan_peer2.conf b/src/transport/test_transport_api_wlan_peer2.conf index 22824e090..c422b3dc9 100644 --- a/src/transport/test_transport_api_wlan_peer2.conf +++ b/src/transport/test_transport_api_wlan_peer2.conf @@ -9,7 +9,7 @@ AUTOSTART = NO [transport-wlan] INTERFACE = mon1 -TESTMODE = 0 +TESTMODE = 2 #PREFIX = gdbserver :2346 [hostlist] @@ -46,7 +46,7 @@ UNIXPATH = /tmp/gnunet-p2-service-transport.sock #PREFIX = xterm -T transport1 -e gdb --command=cmd --args #PREFIX = valgrind --leak-check=full --show-reachable=yes --main-stacksize=104857600 #PREFIX = valgrind --leak-check=full --show-reachable=yes -#PREFIX = valgrind --leak-check=full +PREFIX = valgrind --leak-check=full #PREFIX = valgrind --tool=massif #PREFIX = gdbserver :2346 -- cgit v1.2.3