Archived

This forum has been archived. Please start a new discussion on GitHub.

More flexible Connection interface.

At present Ice doesn't support flexible way to get properties for incoming connection for given method invocation. We can get only generic connection interface via con member of Current parameter.

I't ok in many Ice applications, but when, f.e Glacier2, want to query some impotant information from SSL connection, here is no way to get them, because all necessary data stored in transciever. I can't find the way how to access transiever from invoked method.

I will use a solution which will allow me to solve the given problem. Unfortunately it will lead to small incompatibility of interfaces.

Possible solution:
local interface Connection
{
...
       string getProperty(string name); // for single values, like peerAddr
       PropertyDict getPropertyDict(string name); // for multiply values like certificate chain
}

std::string
Ice::ConnectionI::getProperty(std::string name)
{
     if (_transciever)
         return _transciever->getProperty(name);
     else
         return ""; // or some exception. no matter.
}

PropertyDict
Ice::ConnectionI::getPropertyDict(std::string name)
{
     if (_transciever)
         return _transciever->getPropertyDict(name);
     else
         return PropertyDict(); // or some exception. no matter.
}



Are there any plans to implement such thing (in same or another way), or i can write my own implementation because this feature will not implemented in near feature.

(This modification will be used in GPL project, so no commercial support possible )

Comments

  • marc
    marc Florida
    I was more thinking about an interface hierarchy, such as TcpConnection deriving from Connection. TcpConnection would then offer various TCP related functions, such as getting or setting the buffer size.

    We did not yet put this on our todo list for the 2.2 release. Which GNU project do you need such a feature for?
  • marc wrote:
    I was more thinking about an interface hierarchy, such as TcpConnection deriving from Connection. TcpConnection would then offer various TCP related functions, such as getting or setting the buffer size.
    We did not yet put this on our todo list for the 2.2 release.
    Hierarchy is good enough, but this is a big work. You should expose all possible parameters and methods in initial release. Suppose we want some not implemented parameter for TcpConnection. In my way we can simple add this parameter to getParamter/setParameter implementation and all new application can use it. In inheritance way we should implement TcpConnection2 or some other triks to implement such feature. We can't change interface of TcpConnection because this should break older application.

    May be combined method can be used? For common properties (such as srcAddres, srcPort, bufferSize etc) here will be hierarchy of interfaces and as alternative way with getProperty/setProperty for feature extensions. Or make it similar to Ice facets. But I think than hierarchy + get/set is more flexible and simple to implement (first implement get/set, and then all *Connection hierarchy). As bonus this can be implemented in 2.2 release :) because no huge work needed. We can introduce ConnectionExtended and all old clients will use Connection, and new will use ConnectionExtended. In the feature, all *Connection hierarcy will inherit from ConnectionExtended.
    marc wrote:
    Which GNU project do you need such a feature for?
    It is really "toy" project ;). Offline multiuser client for www.rsdn.ru. (russian developers forum).I wish to investigate Ice features in application to the real project.

    Such feature allow to authentificate client by it certificate and no need in "facade" pattern. Moreover, "facade" looks very complex and hard to implement. With certificate authentification, Glacier (or any custom Router) can simple check for pair certificate (f.e. certificate hash) <=> Session object id and pass this to real server. Optionally, router can set additional parameters to context (such as roles). Real server can safely trust this information and no need to pass any special permission checking interfaces to instantiated objects. Method can simple check ctx["allow_any_what_he_want"] == 1.
    In current session aproach we must implement Session derived "facade" object which in secure system must inherit from all interfaces , provided by server. We can split on several subsession objects, but in general this is the same. Another bad thing that all requests must pass via Glacier router. In high load systems this is a bad idea.
  • matthew
    matthew NL, Canada
    aka50 wrote:
    ...
    In current session aproach we must implement Session derived "facade" object which in secure system must inherit from all interfaces , provided by server. We can split on several subsession objects, but in general this is the same. Another bad thing that all requests must pass via Glacier router. In high load systems this is a bad idea.

    What you say isn't true. Once you have established a session you can contact any object on the server backend if you want. Also, why do you think having all requests pass through glacier is a bad idea?
  • matthew wrote:
    What you say isn't true. Once you have established a session you can contact any object on the server backend if you want.
    I can. But how this methods will know about existing session? User must pass session proxy (or it's Id) to each method. Each server method should fetch user's credentials from glacier2 router or other interface. Additional call, is it necessary?
    If we want to hide such things from user, we _must_ implement session with all methods or allow user to create some "facade" objects which will pass credentials to server's methods. In my mind sequence is:


    Client                    Glacier2                                Server
    -------------------------|---------------------------------------|----------------------------
    
     createSession         --------> |  // Create session with given userid/passwd
       sessPrx             <---------/
    
                                          .-------------------. 
     sessPrx.createFacade  -------------> |   createFuncImpl  |  ---------> |
                                          |                   |  <----------/ func1Prx, func2Prx
                                          `-------------------'
                                               | // Get proxy for some "facade" object 
                           <-------------------/ facadePrx
    
                                     .--------------------------. 
     facadePrx.func1()     --------> |   func1Prx.func1(creds)  |  ---------> |
                                     |                          |  <----------/ reply_func1
                                     `--------------------------'
                                               | // Result passed back
                           <-------------------/ reply_func1
    
    


    In this case we should implement func1 func2 interfaces. Then implement all (or some superset) methods which wraps them in facade object. All such thing need to be syncronized across different source files and binary servers (f.e. backend servers and glacier servers). Or I'm missed something and here is more simple and clean solution?
    My situation is similar to crackajaxx in http://www.zeroc.com/vbulletin/showthread.php?t=1436&highlight=facade

    I think that connection's properties and/or "security context" connections will help here.
    Connection properties can be set by session (via f.e. special ice_setSecurityContext ) and accessed from server's methods directly from Connection object (no need to pass them in each method invocation)
    Security context is similar, but implemented as separate context, which set on negotiation phase after connection was accepted. This can be a part of Ice protocol.
    matthew wrote:
    Also, why do you think having all requests pass through glacier is a bad idea?
    1. double sockets usage -> degrade select performace (kqueue or dev/poll will help, for windows here should be something like WMFO_Reactor)
    1. double memory usage (With large requests this is not a problem, but with huge amount of small requests memory usage doubles due of "buffer" nature of any router)
    2. one additional roundtrip. [recv -> kernel copyout -> kernel copyin -> send] -> recv -> kernel copyout.
    I can enable load balancing in my system by adding additional glacier2 routers, additional backend servers and so on. But this is overkill.

    PS: I wan't say that Ice is bad ;). Ice is a very flexible, clean coded and efficient framework. But it is missing some features and I want to find solution (or help to improve Ice) :
    1. compatible with future Ice releases
    3. reuse existing components and dont write my own
    3. as minimal as possible (or no at all) changes to source code