Bug 31167 - General issues trying to use classes CFReadStream and CFWriteStream
Summary: General issues trying to use classes CFReadStream and CFWriteStream
Status: CONFIRMED
Alias: None
Product: iOS
Classification: Xamarin
Component: Xamarin.iOS.dll (show other bugs)
Version: XI 8.10
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Manuel de la Peña [MSFT]
URL:
Depends on:
Blocks:
 
Reported: 2015-06-16 15:55 UTC by Jon Goldberger [MSFT]
Modified: 2017-02-27 16:30 UTC (History)
4 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report for Bug 31167 on Developer Community or GitHub if you have new information to add and do not yet see a matching new report.

If the latest results still closely match this report, you can use the original description:

  • Export the original title and description: Developer Community HTML or GitHub Markdown
  • Copy the title and description into the new report. Adjust them to be up-to-date if needed.
  • Add your new information.

In special cases on GitHub you might also want the comments: GitHub Markdown with public comments

Related Links:
Status:
CONFIRMED

Description Jon Goldberger [MSFT] 2015-06-16 15:55:28 UTC
## Description

Trying to port some code to use VOIP with UDP and to keep playing the VOIP audio while the app is backgrounded. The issues I have come across are:

1. CFWriteStream's constructor is "internal" while CFReadStream's constructor is public.

2. Both have a DoSetProperty override that is protected, so I can not access this method in order to get to the private P/Invoked method CFReadStreamSetProperty

3. Tried subclassing CFReadStream and making a public method to in turn call DoSetProperty, but once I had this subclass, I am unable to pass an instance of this subclass into another method that takes a CFReadStream and CFWriteStream as out parameters:
CFStream.CreatePairWithSocketToHost(new System.Net.IPEndPoint(new System.Net.IPAddress(new byte[]{127,0,0,1}), 1111), out readStream, out writeStream);
where readStream is an instance of a subclass of CFReadStream, I get a compiler error that MyCFReadStream can not be implicitly converted to a CFReadStream, but casting it to a CFReadStream causes a compiler error, so:
CFStream.CreatePairWithSocketToHost(new System.Net.IPEndPoint(new System.Net.IPAddress(new byte[]{127,0,0,1}), 1111), out (CFReadStream)readStream, out writeStream);
causes error "a ref or out argument must be an assignable variable."


##

Might be able to avoid CFStream classes for the use case that this came up in and just use NSStream which seems to "work as expected" as far as having access to the needed methods, etc.
Comment 1 RogerH 2015-08-10 16:15:49 UTC
I also have a need for CFReadStreamSetProperty and CFWriteStreamSetProperty.

I am already using NSStream in my iOS app for normal sockets and for SSL/TLS sockets.

I want to use NSStream with a secure socket to a remote server which has a self signed certificate.
There are extra properties which can be given to the CFReadStream and CFWriteStream.

Obj-C code from a Blog tells me to implement something like this

NSDictionary *settings = [[NSDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredCertificates,
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsAnyRoot,
[NSNumber numberWithBool:NO], kCFStreamSSLValidatesCertificateChain,
 kCFNull,kCFStreamSSLPeerName,
nil];
            
CFReadStreamSetProperty((CFReadStreamRef)inStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings);
CFWriteStreamSetProperty((CFWriteStreamRef)outStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings);


It looks like the CFReadStreamSetProperties (and CFWriteStreamSetProperties) cannot be called from my application.
Comment 2 David Lilley 2016-10-13 14:20:03 UTC
DoSetProperty &
Comment 3 David Lilley 2016-10-13 14:46:50 UTC
I also think they should be made public  I am using to connected to home webdav servers and often they have self signed cert, which I need to set to be allowed to use. of course the user is made aware of ignoring ssl checks.

beside CFReadStream does not use DoSetProperty itself so pointless to be protected

For those are interested my work around.

NSDictionary aDictionary = NSDictionary.FromObjectAndKey (NSNumber.FromBoolean(false), new NSString("kCFStreamSSLValidatesCertificateChain"));
                    _CFReadStreamSetProperty (aStream, new NSString ("kCFStreamPropertySSLSettings"), aDictionary);
 
...


//https://github.com/xamarin/xamarin-macios/blob/master/src/CoreFoundation/CFReadStream.cs
 [DllImport (Constants.CoreFoundationLibrary)]
        [return: MarshalAs (UnmanagedType.I1)]
        extern static /* Boolean */ bool CFReadStreamSetProperty (/* CFReadStreamRef */ IntPtr stream, /* CFStreamRef */ IntPtr propertyName, /* CFTypeRef */ IntPtr propertyValue);

        bool _CFReadStreamSetProperty (CFReadStream aStream, NSString name, INativeObject value)
        {
            if (name == null)
                throw new ArgumentNullException ("name");
            return CFReadStreamSetProperty (aStream.Handle, name.Handle, value == null ? IntPtr.Zero : value.Handle);
        }
Comment 4 Manuel de la Peña [MSFT] 2017-02-27 16:30:22 UTC
Hello,

I agree, there is no actual reason for it to be protected, I'll update the source to expose the method AND will make sure that the property keys are accessible via Fields.

Thx for the bug report.