Discussion:
[freetds] CS_SERVERADDR tag is not handled correctly in ct_con_props
Stephen Marshall
2014-01-02 14:49:28 UTC
Permalink
FreeTDS 0.91 does not honor the CS_SERVERADDR tag in the ct_con_props
function. This function and tag are used to allow database connections
using a "<host> <port>" syntax.

There is code in FreeTDS that compensates for this problem by allowing the
user to specify the server name as "<host>:<port>". FreeTDS supports this
syntax as a fallback case when a server name cannot be found in the
configuration file. See freetds file src/tds/config.c,
parse_server_name_for_port function for details. However, this is not a
standard part of the TDS protocol. Client applications conforming to the
standard can end up doing the wrong thing. I have noticed this problem in
the sqsh client, but may affect other clients as well.

The connection code should either be fixed or the CS_SERVERADDR macro
should be disabled. The latter would signal to client applications that
CS_SERVERADDR does not work per spec, which would allow client applications
to avoid calling this function when linked against FreeTDS.

Note: this problem was originally submitted as a bug to the sqsh project,
but latter determined to be a problem in FreeTDS. Further details of the
original submission can be found here:
http://sourceforge.net/p/sqsh/bugs/60/

Also note that I tried to fix this myself, but I got a little lost in
mapping of connection information between several different data
structures. It does not seem like the port information is carried through
all of them. With some guidance on how to proceed without inducing side
effects, I would be happy to work on this problem.
Frediano Ziglio
2014-01-06 14:21:39 UTC
Permalink
Post by Stephen Marshall
FreeTDS 0.91 does not honor the CS_SERVERADDR tag in the ct_con_props
function. This function and tag are used to allow database connections
using a "<host> <port>" syntax.
Which "tag" ?
Post by Stephen Marshall
There is code in FreeTDS that compensates for this problem by allowing the
user to specify the server name as "<host>:<port>". FreeTDS supports this
syntax as a fallback case when a server name cannot be found in the
configuration file. See freetds file src/tds/config.c,
parse_server_name_for_port function for details. However, this is not a
standard part of the TDS protocol. Client applications conforming to the
standard can end up doing the wrong thing. I have noticed this problem in
the sqsh client, but may affect other clients as well.
The connection code should either be fixed or the CS_SERVERADDR macro
should be disabled. The latter would signal to client applications that
CS_SERVERADDR does not work per spec, which would allow client applications
to avoid calling this function when linked against FreeTDS.
Note: this problem was originally submitted as a bug to the sqsh project,
but latter determined to be a problem in FreeTDS. Further details of the
http://sourceforge.net/p/sqsh/bugs/60/
Also note that I tried to fix this myself, but I got a little lost in
mapping of connection information between several different data
structures. It does not seem like the port information is carried through
all of them. With some guidance on how to proceed without inducing side
effects, I would be happy to work on this problem.
I do not follow at all.

Frediano
Marc Abramowitz
2014-01-06 14:40:46 UTC
Permalink
My guess is that Stephen is referring to the code around this line in
src/ctlib/ct.c (around line 395) in the ct_con_props function:

case CS_SERVERADDR:

There are comments mentioning that this code is handling the "[hostname]
[port]" syntax but from messages on the sqsh bug report it sounds like,
FreeTDS somehow still fails to connect.
Post by Frediano Ziglio
Post by Stephen Marshall
FreeTDS 0.91 does not honor the CS_SERVERADDR tag in the ct_con_props
function. This function and tag are used to allow database connections
using a "<host> <port>" syntax.
Which "tag" ?
Post by Stephen Marshall
There is code in FreeTDS that compensates for this problem by allowing
the
Post by Stephen Marshall
user to specify the server name as "<host>:<port>". FreeTDS supports
this
Post by Stephen Marshall
syntax as a fallback case when a server name cannot be found in the
configuration file. See freetds file src/tds/config.c,
parse_server_name_for_port function for details. However, this is not a
standard part of the TDS protocol. Client applications conforming to the
standard can end up doing the wrong thing. I have noticed this problem
in
Post by Stephen Marshall
the sqsh client, but may affect other clients as well.
The connection code should either be fixed or the CS_SERVERADDR macro
should be disabled. The latter would signal to client applications that
CS_SERVERADDR does not work per spec, which would allow client
applications
Post by Stephen Marshall
to avoid calling this function when linked against FreeTDS.
Note: this problem was originally submitted as a bug to the sqsh project,
but latter determined to be a problem in FreeTDS. Further details of the
http://sourceforge.net/p/sqsh/bugs/60/
Also note that I tried to fix this myself, but I got a little lost in
mapping of connection information between several different data
structures. It does not seem like the port information is carried
through
Post by Stephen Marshall
all of them. With some guidance on how to proceed without inducing side
effects, I would be happy to work on this problem.
I do not follow at all.
Frediano
_______________________________________________
FreeTDS mailing list
FreeTDS at lists.ibiblio.org
http://lists.ibiblio.org/mailman/listinfo/freetds
Kayak
2014-01-06 14:58:45 UTC
Permalink
Marc is right. By tag, I mean the enum CS_SERVERADDR

Sent from my iPhone
Post by Marc Abramowitz
My guess is that Stephen is referring to the code around this line in
There are comments mentioning that this code is handling the "[hostname]
[port]" syntax but from messages on the sqsh bug report it sounds like,
FreeTDS somehow still fails to connect.
Post by Frediano Ziglio
Post by Stephen Marshall
FreeTDS 0.91 does not honor the CS_SERVERADDR tag in the ct_con_props
function. This function and tag are used to allow database connections
using a "<host> <port>" syntax.
Which "tag" ?
Post by Stephen Marshall
There is code in FreeTDS that compensates for this problem by allowing
the
Post by Stephen Marshall
user to specify the server name as "<host>:<port>". FreeTDS supports
this
Post by Stephen Marshall
syntax as a fallback case when a server name cannot be found in the
configuration file. See freetds file src/tds/config.c,
parse_server_name_for_port function for details. However, this is not a
standard part of the TDS protocol. Client applications conforming to the
standard can end up doing the wrong thing. I have noticed this problem
in
Post by Stephen Marshall
the sqsh client, but may affect other clients as well.
The connection code should either be fixed or the CS_SERVERADDR macro
should be disabled. The latter would signal to client applications that
CS_SERVERADDR does not work per spec, which would allow client
applications
Post by Stephen Marshall
to avoid calling this function when linked against FreeTDS.
Note: this problem was originally submitted as a bug to the sqsh project,
but latter determined to be a problem in FreeTDS. Further details of the
http://sourceforge.net/p/sqsh/bugs/60/
Also note that I tried to fix this myself, but I got a little lost in
mapping of connection information between several different data
structures. It does not seem like the port information is carried
through
Post by Stephen Marshall
all of them. With some guidance on how to proceed without inducing side
effects, I would be happy to work on this problem.
I do not follow at all.
Frediano
_______________________________________________
FreeTDS mailing list
FreeTDS at lists.ibiblio.org
http://lists.ibiblio.org/mailman/listinfo/freetds
_______________________________________________
FreeTDS mailing list
FreeTDS at lists.ibiblio.org
http://lists.ibiblio.org/mailman/listinfo/freetds
Stephen Marshall
2014-01-06 17:10:34 UTC
Permalink
Let me try to explain in better detail:

Problem:
The CS_SERVERADDR enum is not properly honored in the ct_con_props function
call.
For example, this call should effectively set the host and port for a DB
connection, but it results in an error when the connection information is
actually used.
ct_con_props( g_connection,
CS_SET,
CS_SERVERADDR,
(CS_VOID*)server,
CS_NULLTERM,
(CS_INT*)NULL
);
Here: g_connection is a pointer to type CS_CONNECTION, and server is text
of the form "<host> <port>". Note that FreeTDS provides other ways to
specify host and port (e.g. setting the server parameter to
"<host>:<port>"; however, the method using CS_SERVERADDR does not work.

Approaches to fix:
I see two ways to attack this problem. Of course, you may see others.

One approach is to ensure port information is set in the CS_CONNECTION data
structures and then passed to the other internal data structures used to
establish a connection in FreeTDS. This would be a true fix to the
problem, but would require some changes to at least a few internal data
structures.

Another approach is the mark the CS_SERVERADDR tag as disabled in FreeTDS.
This would not actually fix the problem, but would allow client
applications to work around the limitation. However, I think this can be
achieved by simply undefining CS_SERVERADDR in cspublic.h.

If you have any thoughts on ways to fix this, I'm certainly open to
suggestions.

Steve
Post by Kayak
Marc is right. By tag, I mean the enum CS_SERVERADDR
Sent from my iPhone
Post by Marc Abramowitz
My guess is that Stephen is referring to the code around this line in
There are comments mentioning that this code is handling the "[hostname]
[port]" syntax but from messages on the sqsh bug report it sounds like,
FreeTDS somehow still fails to connect.
On Mon, Jan 6, 2014 at 6:21 AM, Frediano Ziglio <freddy77 at gmail.com>
Post by Frediano Ziglio
Post by Stephen Marshall
FreeTDS 0.91 does not honor the CS_SERVERADDR tag in the ct_con_props
function. This function and tag are used to allow database connections
using a "<host> <port>" syntax.
Which "tag" ?
Post by Stephen Marshall
There is code in FreeTDS that compensates for this problem by allowing
the
Post by Stephen Marshall
user to specify the server name as "<host>:<port>". FreeTDS supports
this
Post by Stephen Marshall
syntax as a fallback case when a server name cannot be found in the
configuration file. See freetds file src/tds/config.c,
parse_server_name_for_port function for details. However, this is not
a
Post by Marc Abramowitz
Post by Frediano Ziglio
Post by Stephen Marshall
standard part of the TDS protocol. Client applications conforming to
the
Post by Marc Abramowitz
Post by Frediano Ziglio
Post by Stephen Marshall
standard can end up doing the wrong thing. I have noticed this problem
in
Post by Stephen Marshall
the sqsh client, but may affect other clients as well.
The connection code should either be fixed or the CS_SERVERADDR macro
should be disabled. The latter would signal to client applications
that
Post by Marc Abramowitz
Post by Frediano Ziglio
Post by Stephen Marshall
CS_SERVERADDR does not work per spec, which would allow client
applications
Post by Stephen Marshall
to avoid calling this function when linked against FreeTDS.
Note: this problem was originally submitted as a bug to the sqsh
project,
Post by Marc Abramowitz
Post by Frediano Ziglio
Post by Stephen Marshall
but latter determined to be a problem in FreeTDS. Further details of
the
Post by Marc Abramowitz
Post by Frediano Ziglio
Post by Stephen Marshall
http://sourceforge.net/p/sqsh/bugs/60/
Also note that I tried to fix this myself, but I got a little lost in
mapping of connection information between several different data
structures. It does not seem like the port information is carried
through
Post by Stephen Marshall
all of them. With some guidance on how to proceed without inducing
side
Post by Marc Abramowitz
Post by Frediano Ziglio
Post by Stephen Marshall
effects, I would be happy to work on this problem.
I do not follow at all.
Frediano
_______________________________________________
FreeTDS mailing list
FreeTDS at lists.ibiblio.org
http://lists.ibiblio.org/mailman/listinfo/freetds
_______________________________________________
FreeTDS mailing list
FreeTDS at lists.ibiblio.org
http://lists.ibiblio.org/mailman/listinfo/freetds
Frediano Ziglio
2014-01-06 17:21:06 UTC
Permalink
Post by Stephen Marshall
The CS_SERVERADDR enum is not properly honored in the ct_con_props function
call.
For example, this call should effectively set the host and port for a DB
connection, but it results in an error when the connection information is
actually used.
ct_con_props( g_connection,
CS_SET,
CS_SERVERADDR,
(CS_VOID*)server,
CS_NULLTERM,
(CS_INT*)NULL
);
Here: g_connection is a pointer to type CS_CONNECTION, and server is text
of the form "<host> <port>". Note that FreeTDS provides other ways to
specify host and port (e.g. setting the server parameter to
"<host>:<port>"; however, the method using CS_SERVERADDR does not work.
Now I got it.
Post by Stephen Marshall
I see two ways to attack this problem. Of course, you may see others.
One approach is to ensure port information is set in the CS_CONNECTION data
structures and then passed to the other internal data structures used to
establish a connection in FreeTDS. This would be a true fix to the
problem, but would require some changes to at least a few internal data
structures.
Another approach is the mark the CS_SERVERADDR tag as disabled in FreeTDS.
This would not actually fix the problem, but would allow client
applications to work around the limitation. However, I think this can be
achieved by simply undefining CS_SERVERADDR in cspublic.h.
If you have any thoughts on ways to fix this, I'm certainly open to
suggestions.
Steve
Well, as Sybase write specification while we should stick to it we
should just handle properly this tag. Perhaps the problem is how to
fit this with other port specification. Should CS_SERVERADDR port
override CS_SERVERNAME "host:port" FreeTDS syntax? Perhaps we should
just document the combination as not supported or undefined behaviour.

Frediano
Stephen Marshall
2014-01-06 19:16:50 UTC
Permalink
Post by Stephen Marshall
Post by Stephen Marshall
The CS_SERVERADDR enum is not properly honored in the ct_con_props
function
Post by Stephen Marshall
call.
For example, this call should effectively set the host and port for a DB
connection, but it results in an error when the connection information is
actually used.
ct_con_props( g_connection,
CS_SET,
CS_SERVERADDR,
(CS_VOID*)server,
CS_NULLTERM,
(CS_INT*)NULL
);
Here: g_connection is a pointer to type CS_CONNECTION, and server is text
of the form "<host> <port>". Note that FreeTDS provides other ways to
specify host and port (e.g. setting the server parameter to
"<host>:<port>"; however, the method using CS_SERVERADDR does not work.
Now I got it.
Post by Stephen Marshall
I see two ways to attack this problem. Of course, you may see others.
One approach is to ensure port information is set in the CS_CONNECTION
data
Post by Stephen Marshall
structures and then passed to the other internal data structures used to
establish a connection in FreeTDS. This would be a true fix to the
problem, but would require some changes to at least a few internal data
structures.
Another approach is the mark the CS_SERVERADDR tag as disabled in
FreeTDS.
Post by Stephen Marshall
This would not actually fix the problem, but would allow client
applications to work around the limitation. However, I think this can be
achieved by simply undefining CS_SERVERADDR in cspublic.h.
If you have any thoughts on ways to fix this, I'm certainly open to
suggestions.
Steve
Well, as Sybase write specification while we should stick to it we
should just handle properly this tag. Perhaps the problem is how to
fit this with other port specification. Should CS_SERVERADDR port
override CS_SERVERNAME "host:port" FreeTDS syntax? Perhaps we should
just document the combination as not supported or undefined behaviour.
You raise an interesting idea to use CS_SERVERADDR to set the
CS_SERVERNAME. This seems easier than either of my suggestions. The main
complexity is that servername is passed directly to the ct_connect
function, while CS_SERVERADDR is set ahead of time in the CS_CONNECTION
data structure.

I have implemented your suggestion in the attached patch file for
src/ctlib/ct.c. This required small changes to both ct_con_props and
ct_connect. I tested this change using sqsh 2.4, but creating a test
within FreeTDS itself would be a good idea.

Let me know if this looks ok to you. The part where I changed how
not-NULL values of con->server_addr are interpreted in ct_connect is the
only change that may be prone to side effects. The previous logic appears
to have ignored any server_addr setting that was previously made. Now
server_addr settings override the server name passed into ct_connect.
Post by Stephen Marshall
Frediano
_______________________________________________
FreeTDS mailing list
FreeTDS at lists.ibiblio.org
http://lists.ibiblio.org/mailman/listinfo/freetds
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ct.c.cs_serveraddr_patch
Type: application/octet-stream
Size: 1767 bytes
Desc: not available
Url : http://lists.ibiblio.org/pipermail/freetds/attachments/20140106/0d86e951/attachment.obj
Frediano Ziglio
2014-01-10 00:03:42 UTC
Permalink
Post by Stephen Marshall
Post by Stephen Marshall
Post by Stephen Marshall
The CS_SERVERADDR enum is not properly honored in the ct_con_props
function
Post by Stephen Marshall
call.
For example, this call should effectively set the host and port for a DB
connection, but it results in an error when the connection information is
actually used.
ct_con_props( g_connection,
CS_SET,
CS_SERVERADDR,
(CS_VOID*)server,
CS_NULLTERM,
(CS_INT*)NULL
);
Here: g_connection is a pointer to type CS_CONNECTION, and server is text
of the form "<host> <port>". Note that FreeTDS provides other ways to
specify host and port (e.g. setting the server parameter to
"<host>:<port>"; however, the method using CS_SERVERADDR does not work.
Now I got it.
Post by Stephen Marshall
I see two ways to attack this problem. Of course, you may see others.
One approach is to ensure port information is set in the CS_CONNECTION
data
Post by Stephen Marshall
structures and then passed to the other internal data structures used to
establish a connection in FreeTDS. This would be a true fix to the
problem, but would require some changes to at least a few internal data
structures.
Another approach is the mark the CS_SERVERADDR tag as disabled in
FreeTDS.
Post by Stephen Marshall
This would not actually fix the problem, but would allow client
applications to work around the limitation. However, I think this can be
achieved by simply undefining CS_SERVERADDR in cspublic.h.
If you have any thoughts on ways to fix this, I'm certainly open to
suggestions.
Steve
Well, as Sybase write specification while we should stick to it we
should just handle properly this tag. Perhaps the problem is how to
fit this with other port specification. Should CS_SERVERADDR port
override CS_SERVERNAME "host:port" FreeTDS syntax? Perhaps we should
just document the combination as not supported or undefined behaviour.
You raise an interesting idea to use CS_SERVERADDR to set the
CS_SERVERNAME. This seems easier than either of my suggestions. The main
complexity is that servername is passed directly to the ct_connect
function, while CS_SERVERADDR is set ahead of time in the CS_CONNECTION
data structure.
I have implemented your suggestion in the attached patch file for
src/ctlib/ct.c. This required small changes to both ct_con_props and
ct_connect. I tested this change using sqsh 2.4, but creating a test
within FreeTDS itself would be a good idea.
Let me know if this looks ok to you. The part where I changed how
not-NULL values of con->server_addr are interpreted in ct_connect is the
only change that may be prone to side effects. The previous logic appears
to have ignored any server_addr setting that was previously made. Now
server_addr settings override the server name passed into ct_connect.
Hi,
I was looking at your patch and at Gerhard one. They really touch
same piece of code fixing (it seems) different things. The patch from
Gerhard just add name resolution if a CS_SERVERADDR is passed while
your avoid to parse configuration name (or perhaps do you have same
problem raised by Gerhard?). Looking at the code... well... is not
easy to understand what's is doing! Some points:
- Sybase server name can be different from dns name but your patch
just use dns name so we'll have problems with Sybase servers;
- name resolution should be done so Gerhard patch is correct (I don't
understand why name resolution is not done in a single place);
- current code is actually wrong as it ignores servername passed to
ct_connect if CS_SERVERADDR is used. None of the two patches fix this
issue;
- is not clear what the difference setting server to NULL or "";
- should configuration NEVER be read if CS_SERVERADDR is used? Looking
at libTDS code (tds_read_config_info) seems that an attempt to read
configuration is always done, even for server:port syntax. However
setting server_name to "" should cause only global section to be
parsed.

Well.. just trying to collect some details... no solution yet.
Possibly Gerhard patch adding set to server_name after reading
configuration if servername is valid and CS_SERVERADDR is used (in the
"if (con->server_addr)" statement) ?

Frediano
Stephen Marshall
2014-01-10 03:35:03 UTC
Permalink
Frediano,

Thanks for looking into this. I also find the code a bit confusing. My
answers to your comments are interspersed below.

Steve
Post by Stephen Marshall
On Mon, Jan 6, 2014 at 12:21 PM, Frediano Ziglio <freddy77 at gmail.com>
Post by Stephen Marshall
Post by Stephen Marshall
The CS_SERVERADDR enum is not properly honored in the ct_con_props
function
Post by Stephen Marshall
call.
For example, this call should effectively set the host and port for a
DB
Post by Stephen Marshall
Post by Stephen Marshall
connection, but it results in an error when the connection
information is
Post by Stephen Marshall
Post by Stephen Marshall
actually used.
ct_con_props( g_connection,
CS_SET,
CS_SERVERADDR,
(CS_VOID*)server,
CS_NULLTERM,
(CS_INT*)NULL
);
Here: g_connection is a pointer to type CS_CONNECTION, and server is
text
Post by Stephen Marshall
Post by Stephen Marshall
of the form "<host> <port>". Note that FreeTDS provides other ways to
specify host and port (e.g. setting the server parameter to
"<host>:<port>"; however, the method using CS_SERVERADDR does not
work.
Post by Stephen Marshall
Now I got it.
Post by Stephen Marshall
I see two ways to attack this problem. Of course, you may see others.
One approach is to ensure port information is set in the CS_CONNECTION
data
Post by Stephen Marshall
structures and then passed to the other internal data structures used
to
Post by Stephen Marshall
Post by Stephen Marshall
establish a connection in FreeTDS. This would be a true fix to the
problem, but would require some changes to at least a few internal
data
Post by Stephen Marshall
Post by Stephen Marshall
structures.
Another approach is the mark the CS_SERVERADDR tag as disabled in
FreeTDS.
Post by Stephen Marshall
This would not actually fix the problem, but would allow client
applications to work around the limitation. However, I think this
can be
Post by Stephen Marshall
Post by Stephen Marshall
achieved by simply undefining CS_SERVERADDR in cspublic.h.
If you have any thoughts on ways to fix this, I'm certainly open to
suggestions.
Steve
Well, as Sybase write specification while we should stick to it we
should just handle properly this tag. Perhaps the problem is how to
fit this with other port specification. Should CS_SERVERADDR port
override CS_SERVERNAME "host:port" FreeTDS syntax? Perhaps we should
just document the combination as not supported or undefined behaviour.
You raise an interesting idea to use CS_SERVERADDR to set the
CS_SERVERNAME. This seems easier than either of my suggestions. The
main
complexity is that servername is passed directly to the ct_connect
function, while CS_SERVERADDR is set ahead of time in the CS_CONNECTION
data structure.
I have implemented your suggestion in the attached patch file for
src/ctlib/ct.c. This required small changes to both ct_con_props and
ct_connect. I tested this change using sqsh 2.4, but creating a test
within FreeTDS itself would be a good idea.
Let me know if this looks ok to you. The part where I changed how
not-NULL values of con->server_addr are interpreted in ct_connect is the
only change that may be prone to side effects. The previous logic
appears
to have ignored any server_addr setting that was previously made. Now
server_addr settings override the server name passed into ct_connect.
Hi,
I was looking at your patch and at Gerhard one. They really touch
same piece of code fixing (it seems) different things. The patch from
Gerhard just add name resolution if a CS_SERVERADDR is passed while
your avoid to parse configuration name (or perhaps do you have same
problem raised by Gerhard?). Looking at the code... well... is not
- Sybase server name can be different from dns name but your patch
just use dns name so we'll have problems with Sybase servers;
[Steve] - The CS_SERVERADDR is suppose to use host and port, not Sybase
server name, so I think this is appropriate.

- name resolution should be done so Gerhard patch is correct (I don't
Post by Stephen Marshall
understand why name resolution is not done in a single place);
[Steve] - I thought hostname resolution (dns name to ip address) was done
at a lower level.
Post by Stephen Marshall
- current code is actually wrong as it ignores servername passed to
ct_connect if CS_SERVERADDR is used. None of the two patches fix this
issue;
[Steve] - Since server name is primarily used to lookup host and port, you
really only have two choices if both are specified:
1. Prefer server name passed to ct_connect of CS_SERVERADDR
2. Prefer CS_SERVERADDR over server name

The code previoulsy did #1, my patch changed it to do #2. The rationale
for this was based on behavior in sqsh using both FreeTDS and Sybase
ctlib. When the -S <host>:<port> syntax is used, sqsh passes host and port
as a CS_SERVERADDR parameter AND it passes the <host>:<port> string as the
servername to ct_connect. When sqsh is linked against ctlib, the
CS_SERVERADDR values were honored, indicating ctlib used method #2.
Therefore, I think changing FreeTDS to use method #2 would be a good idea.


- is not clear what the difference setting server to NULL or "";
[Steve] - I don't know either.
Post by Stephen Marshall
- should configuration NEVER be read if CS_SERVERADDR is used?
[Steve] - The only additional issue to what I discussed above is the case
where you could look up parameters other than host and port by server name,
e.g. tds version or client charset. However, I think that if someone is
explicitly passing host and port numbers, it is unlikely they are relying
on the configuration file for anything, so I don't think this would be bad
behavior. In other words, if CS_SERVERADDR is used, client should be
expect to ct_con_props to set other pieces of configuration, like protocol
version, client character encoding.

Looking at libTDS code (tds_read_config_info) seems that an attempt to read
Post by Stephen Marshall
configuration is always done, even for server:port syntax. However
setting server_name to "" should cause only global section to be
parsed.
Well.. just trying to collect some details... no solution yet.
Possibly Gerhard patch adding set to server_name after reading
configuration if servername is valid and CS_SERVERADDR is used (in the
"if (con->server_addr)" statement) ?
Frediano
_______________________________________________
FreeTDS mailing list
FreeTDS at lists.ibiblio.org
http://lists.ibiblio.org/mailman/listinfo/freetds
James K. Lowden
2014-01-10 23:39:58 UTC
Permalink
On Fri, 10 Jan 2014 00:03:42 +0000
Post by Frediano Ziglio
- should configuration NEVER be read if CS_SERVERADDR is used? Looking
at libTDS code (tds_read_config_info) seems that an attempt to read
configuration is always done, even for server:port syntax. However
setting server_name to "" should cause only global section to be
parsed.
ISTM the global section of freetds.conf should apply regardless.

Global is global. If you don't want a global setting, don't set it.
If you want to override it, use an environment variable.

Another way to think about it: just because we don't need to use
freetds.conf to resolve a name for a particular host when an address is
provided doesn't imply that non-host (global) settings are invalid.

The configuration establishment code was never my favorite. Too much
logic for very little data. It could use some TLC from someone with a
preference for table-driven design.

HTH.

--jkl
Stephen Marshall
2014-01-13 16:57:12 UTC
Permalink
Overall, I agree with comments from both Frediano and James about honoring
the settings in the configuration file, unless they are specifically
overridden by calls to ct_con_props. However, I'm concerned about the
magnitude of changes to accomplish this. Connection information can come
from a lot of directions, including:
* ct_con_props calls
* lookup from global part of freetds.conf file
* lookup by server name from freetds.conf file
* environment variables
* heuristic rules, e.g. special case when server name matches the pattern
"<host>:<port>".

In my opinion, the priority of these information sources should be, from
lowest to highest priority:
1. Hard coded defaults
2. Environment variables
3. Global config values from freetds.conf
4. Server-specific values from freetds.conf
5. Settings specifically made by calls to ct_con_props

The code should be reworked to set connection parameters in priority order,
with each level in the hierarchy overriding settings in the previous level.
The special case heuristics should all be removed, if possible.

As far as I can tell, such a change would require the connection logic to
be completely refactored. This is no small task, and would require a lot
of testing to weed out unintended side effects. Is there someone in the
FreeTDS community with an appetite for this level of change to the
conniption subsystem?
Post by James K. Lowden
On Fri, 10 Jan 2014 00:03:42 +0000
Post by Frediano Ziglio
- should configuration NEVER be read if CS_SERVERADDR is used? Looking
at libTDS code (tds_read_config_info) seems that an attempt to read
configuration is always done, even for server:port syntax. However
setting server_name to "" should cause only global section to be
parsed.
ISTM the global section of freetds.conf should apply regardless.
Global is global. If you don't want a global setting, don't set it.
If you want to override it, use an environment variable.
Another way to think about it: just because we don't need to use
freetds.conf to resolve a name for a particular host when an address is
provided doesn't imply that non-host (global) settings are invalid.
The configuration establishment code was never my favorite. Too much
logic for very little data. It could use some TLC from someone with a
preference for table-driven design.
HTH.
--jkl
_______________________________________________
FreeTDS mailing list
FreeTDS at lists.ibiblio.org
http://lists.ibiblio.org/mailman/listinfo/freetds
James K. Lowden
2014-01-15 04:16:02 UTC
Permalink
On Mon, 13 Jan 2014 11:57:12 -0500
Post by Stephen Marshall
In my opinion, the priority of these information sources should be,
1. Hard coded defaults
2. Environment variables
3. Global config values from freetds.conf
4. Server-specific values from freetds.conf
5. Settings specifically made by calls to ct_con_props
The order is
Post by Stephen Marshall
1. Hard coded defaults
3. Global config values from freetds.conf
4. Server-specific values from freetds.conf
2. Environment variables
5. Settings specifically made by calls to ct_con_props
because the user may not have access to the configuration file but
always has access to his own environment. They don't override
application-driven settings because the application
may have a need for particular settings irrespective of the user's need
or expectation.

I thought that was accepted practice, but a quick tour through my home
directory yields very few examples of programs that use both a
configuration file and environment variables. Of those that do, they
cover disjoint attributes. For example, the HTML checker "tidy" has a
configuration file, and the only environment variable it honors governs
the name of that file. xdvi honors a bunch of variables that are
truly *environment* variables, such as VISUAL and TMPDIR, and none that
overlap what might be found in .xdvirc.

There would seem to be a good case for simplification.
Post by Stephen Marshall
The code should be reworked to set connection parameters in priority
order, with each level in the hierarchy overriding settings in the
previous level.
That's what it does now.
Post by Stephen Marshall
As far as I can tell, such a change would require the connection
logic to be completely refactored. This is no small task,
The problem is well defined and confined to the startup code, basically
config.c. That code wins no beauty contests today. It's not awful,
but it could certainly be better.

A good start would be a proper parser to read the configuration
file, and a data structure to hold the configurable elements (or just
use getenv and putenv). Iterate the parser over the available files,
and voila. Write a little standalone test utility to exercise
library and print the results -- helpful for users testing their
configurations -- and then integrate it into the existing system.

I've often thought the parser could be simplied if the configuration
file grammar were simplifed. Suppose the structure were:

.freeds/
.freetds/global
.freetds/host1
.freetds/host2

with each file representing a server, containing only lines of the form

# comment
option = value

Such file could be parsed as a regular language (using regular
expressions) and the user would have an easier time knowing a server's
settings because

$ cat ~/.freetds/servername

would work with tab-completion and never yield more than a few lines.

--jkl
Marc Abramowitz
2014-01-15 17:11:39 UTC
Permalink
Post by James K. Lowden
a quick tour through my home
directory yields very few examples of programs that use both a
configuration file and environment variables. Of those that do, they
cover disjoint attributes
The one that popped into my head right away was pip, the Python package
installer. They actually wrote their configuration code in such a way I
believe that every configuration value can get set by command-line option,
configuration file, or environment variable (with a predictable name).
Though I mostly, for whatever reason, tend to stick to the former two. I
have a tendency to use environment variables for configuration when I'm
setting up Jenkins jobs. Configuration files are not so obvious (people
don't go looking in /home/jenkins to see what's configured) but environment
variables can set within a job so this is a good place to set something
where people see it and it applies to all commands. In particular I set an
environment variable for some other tools (py.test, tox) to force them to
use colored output even though they're not writing to a tty. You can look
at pip though -- if you want inspiration.

http://www.pip-installer.org/en/latest/configuration.html
Post by James K. Lowden
I've often thought the parser could be simplied if the configuration
.freeds/
.freetds/global
.freetds/host1
.freetds/host2
with each file representing a server, containing only lines of the form
# comment
option = value
That would be cool. Another alternative is to stay with one official file
and have a syntax for including other files -- esp. if you have the
Apache-style include everything in a directory syntax -- e.g.:

include .freetds/conf.d/*.conf

But I don't feel strongly about this at all -- just a random idea.
Loading...