Memory leak when using global variable in a swift function from C

I have an networ application based in NetworkExtensions. The core of the application is in C and from there I call Swift functions using a pointer function API. There is a Swift object that implements NEPacketTunnelProvider used to send packets to the TUN interface.

When the C part of the code receive a packet, it sends the pointer of the processed packet to swift in order it could be sent to the tun interface. As the function to be called from C cannot be formed from a closure that captures context, I create a global variable inicialized with the created NEPacketTunnelProvider which have the function to send to tun. We have a memory leak that occurs when this function use the global variable object to send the packet to the tun interface. How I can prevent this memory leak to happen? The scheleton of the code is:


swift

var ptp:PacketTunnelProvider?


func ptp_write_to_tun(buffer: UnsafeMutablePointer<CChar>, length:Int32){

var protocolArray:[NSNumber] = [0x02]

var packetsArray = [Data]()

var packet:Data = Data(bytesNoCopy:buffer,count:Int(length),deallocator: .none)

packetsArray.append(packet!)

// Memory leak in the following line

ptp.packetFlow.writePackets(packetsArray, withProtocols: protocolArray)

}


class PacketTunnelProvider: NEPacketTunnelProvider{


var oor_callbacks:iOS_CLibCallbacks?

override func startTunnel(...){

...

ptp = self

oor_callbacks = iOS_CLibCallbacks(

ptp_write_to_tun: {(buffer, length) in ptr.ptp_write_to_tun(buffer: buffer, length: length)}

)

iOS_CLibCallbacks_setup(&oor_callbacks!)

...

}

-------

.h


typedef struct iOS_CLibCallbacks iOS_CLibCallbacks;


struct iOS_CLibCallbacks {

void (* _Nonnull ptp_write_to_tun)(char * _Nonnull buffer, int length);

};



The buffer with the packet to be send is a unique char array rewrited for each received packet to be processed (remove header of the packet and send to tun/app)


Thanks in advance

What are the symptoms of this memory leak? Is this something reported by the Leaks instrument? Or are you using “leak” in some more generic fashion?

As the function to be called from C cannot be formed from a closure that captures context, I create a global variable

That’s a weird way to do things. Most C APIs that support callbacks also allow you to pass in a

void *
pointer for callback-specific data (typically described as an info pointer, a cookie, a refCon, or something else). You can use this to get back to a Swift closure (see this post) or use it to store the object pointer and then have the C calling convention Swift function recover
self
from that. For an example of the latter, check out my use of
CFHostSetClient
in the Swift part of CFHostSample.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
Memory leak when using global variable in a swift function from C
 
 
Q